(一)Maven详解之聚合与继承

说到聚合与继承咱们都很熟悉,maven一样也具有这样的设计原则,下面咱们来看一下Maven的pom如何进行聚合与继承的配置实现。html


1、为何要聚合?java

随着技术的飞速发展和各种用户对软件的要求愈来愈高,软件自己也变得愈来愈复杂,而后软件设计人员开始采用各类方式进行开发,因而就有了咱们的分层架构、分模块开发,来提升代码的清晰和重用。针对于这一特性,maven也给予了相应的配置。spring

情景分析一:apache

咱们在开发过程当中,建立了2个以上的模块,每一个模块都是一个独立的maven project,在开始的时候咱们能够独立的编译和测试运行每一个模块,可是随着项目的不断变大和复杂化,咱们指望可以使用简单的操做来完成编译等工做,这时Maven给出了聚合的配置方式。编程

所谓聚合,顾名思义,就是把多个模块或项目聚合到一块儿,咱们能够创建一个专门负责聚合工做的Maven project ---  aggregator。安全

创建该project的时候,咱们要注意如下几点:架构

1.该aggregator自己也作为一个Maven项目,它必须有本身的POMmaven

2.它的打包方式必须为: packaging工具

3.引入了新的元素:modules---module测试

4.版本:聚合模块的版本和被聚合模块版本一致

5.relative path:每一个module的值都是一个当前POM的相对目录

6.目录名称:为了方便的快速定位内容,模块所处的目录应当与其artifactId一致(Maven约定而不是硬性要求),总之,模块所处的目录必须和<module>模块所处的目录</module>相一致。

7.习惯约定:为了方便构建,一般将聚合模块放在项目目录层的最顶层,其它聚合模块做为子目录存在。这样当咱们打开项目的时候,第一个看到的就是聚合模块的POM

8.聚合模块减小的内容:聚合模块的内容仅仅是一个pom.xml文件,它不包含src/main/java、src/test/java等目录,由于它只是用来帮助其它模块构建的工具,自己并无实质的内容。

9.聚合模块和子模块的目录:他们能够是父子类,也能够是平行结构,固然若是使用平行结构,那么聚合模块的POM也须要作出相应的更改。

2、为何要继承?

作面向对象编程的人都会以为这是一个没意义的问题,是的,继承就是避免重复,maven的继承也是这样,它还有一个好处就是让项目更加安全

情景分析二:咱们在项目开发的过程当中,可能多个模块独立开发,可是多个模块可能依赖相同的元素,好比说每一个模块都须要Junit,使用spring的时候,其核心jar也必须都被引入,在编译的时候,maven-compiler-plugin插件也要被引入

如何配置继承:

1.说到继承确定是一个父子结构,那么咱们在aggregator中来建立一个parent project

2.<packaging>: 做为父模块的POM,其打包类型也必须为POM

3.结构:父模块只是为了帮助咱们消除重复,因此它也不须要src/main/java、src/test/java等目录

4.新的元素:<parent> , 它是被用在子模块中的

5.<parent>元素的属性:<relativePath>: 表示父模块POM的相对路径,在构建的时候,Maven会先根据relativePath检查父POM,若是找不到,再从本地仓库查找

6.relativePath的默认值: ../pom.xml

7.子模块省略groupId和version: 使用了继承的子模块中能够不声明groupId和version, 子模块将隐式的继承父模块的这两个元素

3、可被继承的POM元素

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

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

description: 项目的描述信息

organization: 项目的组织信息

inceptionYear: 项目的创始年份

url: 项目的URL地址

developers: 项目开发者信息

contributors: 项目的贡献者信息

distributionManagement: 项目的部署配置

issueManagement: 项目的缺陷跟踪系统信息

ciManagement: 项目的持续集成系统信息

scm: 项目的版本控制系统信息

mailingLists: 项目的邮件列表信息

properties: 自定义的maven属性

dependencies: 项目的依赖配置

dependencyManagement: 项目的依赖管理配置

repositories: 项目的仓库配置

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

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

4、maven的依赖管理

咱们知道dependencies是能够被继承的,这个时候咱们就想到让咱们的发生了共用的依赖元素转移到parent中,这样咱们又进一步的优化了配置。但是问题也随之而来,若是有一天我建立了一个新的模块,可是这个模块不须要这些parent的依赖,这时候如何处理?

是的,maven的依赖管理就是来解决这个问题的

增长一个新的元素:dependencyManagement

从上面的列表中咱们发现dependencyManagement也是能够被继承的,这偏偏知足了咱们的须要,它既可以让子模块继承到父模块的依赖配置,又能保证子模块依赖使用的灵活性

dependencyManagement的特性:在dependencyManagement中配置的元素既不会给parent引入依赖,也不会给它的子模块引入依赖,仅仅是它的配置是可继承的

最佳实践:

这时候咱们就能够在父POM中声明这些依赖:

[html] view plaincopy在CODE上查看代码片派生到个人代码片

  1. <span style="white-space:pre">    </span><properties>  

  2.         <target.version>2.5.6</target.version>  

  3.     </properties>  

  4.   

  5.     <dependencyManagement>  

  6.         <dependencies>  

  7.             <dependency>  

  8.                 <groupId>your groupId</groupId>  

  9.                 <artifactId>your artifactId</artifactId>  

  10.                 <version>${target.version}</version>  

  11.             </dependency>  

  12.         </dependencies>  

  13.     </dependencyManagement>  


子模块的POM继承这些配置:子模块继承这些配置的时候,仍然要声明groupId和artifactId,表示当前配置是继承于父POM的,从而直接使用父POM的版本对应的资源

[html] view plaincopy在CODE上查看代码片派生到个人代码片

  1. <span style="white-space:pre">        </span><dependencies>  

  2.             <dependency>  

  3.                 <groupId>your groupId</groupId>  

  4.                 <artifactId>your artifactId</artifactId>  

  5.             </dependency>  

  6.         </dependencies>  


这个能够有效的避免多个子模块使用依赖版本不一致的状况,有助于下降依赖冲突的概率。注:只有子模块配置了继承的元素,才会真正的有效,不然maven是不会加载父模块中声明的元素。

5、Maven的插件管理

再增长一个新的元素:<pluginManagement>

这个元素和<dependencyManagement>相相似,它是用来进行插件管理的。

在咱们项目开发的过程当中,也会频繁的引入插件,因此解决这些复杂配置的方法就是使用插件管理

咱们能够在父POM中作以下声明:

[html] view plaincopy在CODE上查看代码片派生到个人代码片

  1. <span style="white-space:pre">    </span><build>  

  2.         <pluginManagement>  

  3.             <plugins>  

  4.                 <plugin>  

  5.                     <groupId></groupId>  

  6.                     <artifactId></artifactId>  

  7.                     <version></version>  

  8.                     <executions>  

  9.                         <execution>  

  10.                             <id></id>  

  11.                             <goals>  

  12.                                 <goal></goal>  

  13.                             </goals>  

  14.                             <phase></phase>  

  15.                             <configuration>  

  16.                                 <source></source>  

  17.                                 <target></target>  

  18.                             </configuration>  

  19.                         </execution>  

  20.                     </executions>  

  21.                 </plugin>  

  22.             </plugins>  

  23.         </pluginManagement>  

  24.     </build>  



在子模块中,咱们能够直接继承

[html] view plaincopy在CODE上查看代码片派生到个人代码片

  1. <span style="white-space:pre">    </span><build>  

  2.         <plugins>  

  3.             <plugin>  

  4.                 <groupId>org.apache.maven.plugins</groupId>  

  5.                 <artifactId>maven-compiler-plugin</artifactId>  

  6.             </plugin>  

  7.         </plugins>  

[html] view plaincopy在CODE上查看代码片派生到个人代码片

  1. <pre name="code" class="html"><span style="white-space:pre">    </span></build>  


咱们会发现,继承的细节上和<dependencyManagement>几乎同样。


6、聚合与继承的总结

当咱们明白聚合与继承的细节以后,咱们会发现:

对于聚合模块来讲,它知道有哪些被聚合的模块,而对于被聚合的模块来讲,它们不知道被谁聚合了,也不知道它的存在

对于继承关系的父POM来讲,它不知道本身被哪些子模块继承了,对于子POM来讲,它必须知道本身的父POM是谁

在一些最佳实践中咱们会发现:一个POM既是聚合POM,又是父POM,这么作主要是为了方便。

相关文章
相关标签/搜索