6 Maven聚合与集成
Maven的聚合特性能够把项目的各个模块聚合在一起构件,而Maven的继承特性能够帮助抽取各个模块相同的依赖和插件等配置,简化POM的同时,还能促进各个模块配置的一致性。
1.聚合
为了能使用一条命令构建两个模块A,B,需要创建一个新的模块G,然后通过模块构建整个项目的所有模块。G本身就是一个Maven项目,它必须有自己的POM,不过同时作为一个聚合项目,POM的packaging必须是pom。如下,否则无法构建。
<packaging>pom</packaging>
<modules>
<module>modelA</module>
<module>modelB</module>
</modules>
</modules>:实现聚合的最核心配置。用户可以通过在一个打包方式为pom的Maven项目中声明任意数量的module元素来实现模块的聚合。
一般情况,模块所处的目录名称应该与其artifactId一直。不过不是硬性要求。推荐这么做。
如何构建:Maven首先解析聚合模块的名称,不是artifactId,这是为何要在pom中配置合理的name字段。目的更好的清晰输出。
2.继承
2.1 父POM
可以使用继承解决重复的配置。
可以创建一个父模块。有一个pom文件,与其他模块使用相同的groupId和version。使用artifactId为parent表示父模块。
其他模块使用继承。
groupId、artifactId和version指定父模块的坐标。是必须的,relativePath表示父模块POM的相应路径。Maven首先从relativePath检查父POM,如果找不到则从本地仓库查找。默认值是 . ./pom.xml 。就是说,Maven默认父POM在上一层目录下。
正确设置relativePath非常重要:如果父模块没有安装到本地仓库,relativePath路径存在问题,则找不到父POM,导致构件失败。如果根据relativePath找到父pom,它就不需要再检查本地仓库。
groupId和version也可以继承。artifactId需要自己显示声明,否则会出现坐标冲突。
2.2可继承的POM元素
2.3 依赖管理
当A,B继承W,当将A,B模块的所有依赖都写在W中的时候,现在添加C模块,但是C模块并不依赖某些构件。怎么办?
Maven提供的dependencyManagement元素,能让子模块继承到父模块的依赖配置,又能保证子模块依赖使用的灵活性。在dependencyManagement元素下依赖声明不会引入实际的依赖,不过它能约束dependencies下的依赖使用。
例子:
父POM配置:
子POM配置:
子POM中的依赖配置较原来简单了一些,所有的配置值配置了groupId和artifactId。省去了version。还可以省略范围(scope标签)。
使用这种依赖管理机制似乎不能减少太多pom配置。但是建议使用,原因:父POM使用dependencyManagement声明依赖能够统一项目范围中的依赖版本,减少多个子模块版本依赖不一致情况,降低依赖冲突。
如果子模块不声明依赖的使用,不会产生任何实际效果。
scope的import属性:导入依赖范围;只对dependencyManagement元素下才有效果,使用该范围的依赖通常指向一个POM,作用是将目标POM中的dependencyManagement配置导入到当前POM的dependencyManagement元素中。
例子:
注意:type为pom,import一般都指向打包类型为pom的模板,如果多个项目,它们使用的依赖版本都是一致的,可以定义一个dependencyManagement专门管理,各个项目导入这些依赖管理配置。
2.4 插件管理
使用pluginManagement元素管理插件。也不会造成实际的插件调用行为,当POM中配置了真正的plugin元素,并且其groupId和artifactId与pluginManagement中的配置的插件配置匹配时,pluginManagement的配置才会有实际插件行为。
3、聚合与继承的关系
聚合:为了方便快捷构件项目;对于聚合模块来说,它知道哪些被聚合的模块,被聚合的模块不知道这个聚合模块的存在。
继承:主要为了清除重复配置。父POM不知道哪些子模块,子模块知道父模块。
相同点:POM的packaging必须是pom。聚合模块与继承关系中的父模块除了POM之外没有实际的内容。在实际项目中,一个pom及时聚合pom又是父pom。
4、约定优于配置
不多说,使用工具和框架都知道!!!
5、反应堆
反应堆(Reactor):所有模块组成一个构建结构。从而自动计算出合理的构件顺序。
5.1 反应堆顺序
Maven按序读取POM,如果POM没有依赖模块,那就构件该模块,否则先构建其依赖块,如果依赖块还依赖其他模块,则进一步先构建依赖的依赖。如果出现循环则Maven报错。
5.2 裁剪反应堆
如果用户仅仅构建反应堆中的某些个模块。
Maven提供很多的命令行选项支持裁剪反应堆。
例子: