首页 > 代码库 > (二)Maven 基本概念——依赖、生命周期、仓库管理、聚合&继承

(二)Maven 基本概念——依赖、生命周期、仓库管理、聚合&继承

1. 依赖配置

  1.1 依赖配置主要包含如下元素:

<!--添加依赖配置-->   
<dependencies>

<!--项目要使用到junit的jar包,所以在这里添加junit的jar包的依赖-->
<dependency>
  <groupId>junit</groupId>
  <artifactId>junit</artifactId>
  <version>4.9</version>
  <scope>test</scope>
</dependency>

<!--项目要使用到Hello的jar包,所以在这里添加Hello的jar包的依赖-->
<dependency>
  <groupId>me.gacl.maven</groupId>
  <artifactId>Hello</artifactId>
  <version>0.0.1-SNAPSHOT</version>
  <scope>compile</scope>
</dependency>

</dependencies>

   1.2  依赖范围

     依赖范围scope用来控制依赖和编译,测试,运行的classpath的关系. 主要的是三种依赖关系如下:

    1.compile 默认编译依赖范围。对于编译,测试,运行三种classpath都有效
    2.test:测试依赖范围。只对于测试classpath有效
    3.provided:已提供依赖范围。对于编译,测试的classpath都有效,但对于运行无效。因为由容器已经提供,例如servlet-api
    4.runtime:运行时提供。例如:jdbc驱动

    1.3  传递性依赖

  MakeFriends.jar直接依赖于HelloFriends.jar,而HelloFriends.jar又直接依赖于Hello.jar,那么MakeFriends.jar也依赖于Hello.jar,这就是传递性依赖,只不过这种依赖是间接依赖,如下图所示:

  技术分享

 

2. Maven三大生命周期

  Maven有三套相互独立的生命周期,请注意这里说的是"三套",而且"相互独立",这三套生命周期分别是:

  1. Clean Lifecycle 在进行真正的构建之前进行一些清理工作。
  2. Default Lifecycle 构建的核心部分,编译,测试,打包,部署等等。
  3. Site Lifecycle 生成项目报告,站点,发布站点。
  再次强调一下它们是相互独立的,你可以仅仅调用clean来清理工作目录,仅仅调用site来生成站点。当然你也可以直接运行 mvn clean install site 运行所有这三套生命周期。 
 Default生命周期是Maven生命周期中最重要的一个,绝大部分工作都发生在这个生命周期中。这里,只解释一些比较重要和常用的阶段:
  • process-resources 复制并处理资源文件,至目标目录,准备打包。

 

  • compile 编译项目的源代码。

 

  • process-test-resources 复制并处理资源文件,至目标测试目录。

  • test-compile 编译测试源代码。

  • process-test-classes

  • test 使用合适的单元测试框架运行测试。这些测试代码不会被打包或部署。

  • prepare-package

  • package 接受编译好的代码,打包成可发布的格式,如 JAR 。

  • install 将包安装至本地仓库,以让其它项目依赖。

  • deploy 将最终的包复制到远程的仓库,以让其它开发人员与项目共享。

运行任何一个阶段的时候,它前面的所有阶段都会被运行,这也就是为什么我们运行mvn install 的时候,代码会被编译,测试,打包。此外,Maven的插件机制是完全依赖Maven的生命周期的,因此理解生命周期至关重要。
 
 3. 仓库管理

3.1、Maven仓库

  用来统一存储所有Maven共享构建的位置就是仓库

3.2、Maven仓库布局

  根据Maven坐标定义每个构建在仓库中唯一存储路径,大致为:groupId/artifactId/version/artifactId-version.packaging

3.3、仓库的分类

     3.3.1、本地仓库

    每个用户只有一个本地仓库,默认是在~/.m2/repository/,~代表的是用户目录

     3.3.2、远程仓库
    1、中央仓库:Maven默认的远程仓库,URL地址:http://search.maven.org/

        2、私服(Nexus):是一种特殊的远程仓库,它是架设在局域网内的仓库     下载地址:https://www.sonatype.com/download-oss-sonatype

  技术分享
私服介绍:
     通过建立自己的私服,就可以降低中央仓库负荷、节省外网宽带、加速Maven构建、自己部署构件等,从而高效的使用Maven。有三种专门的Maven仓库管理软件可以用来帮助大家建立私服:Apache基金会的Archiva、JFrog的Artifactory和Sonatype的Nexus。目前来说,Nexus应该是当前最流行的Maven仓库管理软件。
搭建nexus私服的目的
  为什么要搭建nexus私服,原因很简单,有些公司都不提供外网给项目组人员,因此就不能使用maven访问远程的仓库地址,所以很有必要在局域网里找一台有外网权限的机器,搭建nexus私服,然后开发人员连到这台私服上,这样的话就可以通过这台搭建了nexus私服的电脑访问maven的远程仓库。
    Nexus架构
  技术分享
技术分享

 

nexus-2.14.3-02:该目录包含了Nexus运行所需要的文件,如启动脚本、依赖jar包等。

sonatype-work:该目录包含了Nexus生成的配置文件、日志文件、仓库文件等。
  
启动服务时必须要保证8081端口没有被其他程序占用,否则是无法启动服务的。
(D:\Program Files (x86)\nexus-2.14.3-02-bundle\nexus-2.14.3-02\bin\jsw\windows-x86-64目录下,直接运行console-nexus.bat脚本启动)
技术分享
技术分享
启动成功后打开浏览器访问 http://localhost:8081/nexus 就能看到Nexus的界面了
Nexus拥有全面的权限控制功能,默认的Nexus访问都是匿名的,而匿名用户仅包含一些基本的权限,要全面学习和管理Nexus,就必须以管理员方式登录。可以单击右上角的Log In进行登录,Nexus默认管理员用户名和密码为admin/admin123。
 
已登录界面:
技术分享
 
要停止Nexus,可以在命令行按Ctrl+C键。
关于Bundle安装的一个常见问题是端口冲突。Nexus Bundle默认使用的端口是8081,如果该端口已经被其他应用程序占用,或者你想使用80端口开放Nexus服务,则编辑文件D:\Program Files (x86)\nexus-2.14.3-02-bundle\nexus-2.14.3-02\conf\nexus.properties,找到属性application-port,按需要将默认值8081改成其他端口号,然后保存该文件,重启Nexus便可。
 
4. 聚合&继承
  4.1 如果我们想一次构建多个项目模块,那我们就需要对多个项目模块进行聚合
    在平时的开发中,项目往往会被划分为好几个模块,比如common公共模块、system系统模块、log日志模块、reports统计模块、monitor监控模块等等。这时我们肯定会出现这么一个需要,我们需要一次构件多个模块,而不用每个模块都去mvn clean install一次,Maven聚合就是用来实现这个需求的。

   例如:对项目的Hello、HelloFriend、MakeFriends这三个模块进行聚合

 <modules>       <module>../Hello</module>         <module>../HelloFriend</module>               <module>../MakeFriends</module> </modules>
   其中module的路径为相对路径。
     聚合模块下的内容只需要POM文件,它不像其他模块那样有src/main/java、src/test/java等目录。他只是用来帮助聚合其他模块构建,他本身并不会有过多的实质内容。
最后运行mvn clean install命令,Maven会分析聚合模块的POM、分析要构建的模块、并计算出一个反应堆构建顺序,然后根据这个顺序依次构建各个模块,这样便可以一次性构建所有聚合的模块。
  4.2  继承为了消除重复,我们把很多相同的配置提取出来,例如:grouptId,version等
     如果多个模块出现相同的依赖包,这样在pom.xml文件的内容出现了冗余、重复的内容,解决这个问题其实使用Maven的继承机制即可,就像Java的继承一样,父类就像一个模板,子类继承自父类,那么有些通用的方法、变量都不必在子类中再重复声明了。Maven的继承机制类似,在一个父级别的Maven的pom文件中定义了相关的常量、依赖、插件等等配置后,实际项目模块可以继承此父项目 的pom文件,重复的项不必显示的再声明一遍了,相当于父Maven项目就是个模板,等着其他子模块去继承。不过父Maven项目要高度抽象,高度提取公共的部分(交集),做到一处声明,多处使用。

    继承代码过程中,可以定义属性,例如:

<properties>     <project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>     <junit.version>4.9</junit.version>     <maven.version>0.0.1-SNAPSHOT</maven.version> </properties>

  访问属性的方式为${junit.version},例如:

 <dependency>     <groupId>junit</groupId>     <artifactId>junit</artifactId>     <version>${junit.version}</version>     <scope>test</scope> </dependency>   

    可继承的POM元素

  groupId和version是可以被继承的,那么还有哪些POM元素可以被继承呢?以下是一个完整的列表,并附带了简单的说明:

    • groupId :项目组 ID ,项目坐标的核心元素;  

    • version :项目版本,项目坐标的核心元素;  

    • description :项目的描述信息;  

    • organization :项目的组织信息;  

    • inceptionYear :项目的创始年份;  

    • url :项目的 url 地址;  

    • develoers :项目的开发者信息;  

    • contributors :项目的贡献者信息;  

    • distributionManagerment :项目的部署信息;  

    • issueManagement :缺陷跟踪系统信息;  

    • ciManagement :项目的持续继承信息;  

    • scm :项目的版本控制信息;  

    • mailingListserv :项目的邮件列表信息;  

    • properties :自定义的 Maven 属性;  

    • dependencies :项目的依赖配置;  

    • dependencyManagement :醒目的依赖管理配置;  

    • repositories :项目的仓库配置;  

    • build :包括项目的源码目录配置、输出目录配置、插件配置、插件管理配置等;  

    • reporting :包括项目的报告输出目录配置、报告插件配置等。

 4.3  父模块用 dependencyManagement  进行管理
<dependencyManagement>      <dependencies>
<dependency> <groupId>junit</groupId> <artifactId>junit</artifactId> <version>${junit.version}</version> <scope>test</scope> </dependency>
<dependency> <groupId>cn.zang.maven</groupId> <artifactId>HelloFriend</artifactId> <version>${maven.version}</version> <type>jar</type> <scope>compile</scope> </dependency>
</dependencies> </dependencyManagement>
  这样的好处是子模块可以有选择性的继承,而不需要全部继承。
     插件的继承与依赖的继承是类似的,这里不过多的说明,插件也有一个<pluginManagement></pluginManagement>元素,放在下面的插件也表示为可选的。
  4.4 聚合与继承的关系

     区别 :

      1.对于聚合模块来说,它知道有哪些被聚合的模块,但那些被聚合的模块不知道这个聚合模块的存在。

      2.对于继承关系的父POM来说,它不知道有哪些子模块继承于它,但那些子模块都必须知道自己的父POM是什么。

    共同点 :

      1.聚合POM与继承关系中的父POM的packaging都是pom。

      2.聚合模块与继承关系中的父模块除了POM之外都没有实际的内容。

    图示:

技术分享

(二)Maven 基本概念——依赖、生命周期、仓库管理、聚合&继承