聚合和继承
聚合解决什么问题?
当一个项目分成多个模块开发,如何一次执行整个项目,而不是分别执行每个模块
1 | <modelVersion>4.0.0</modelVersion> |
注意:
- 该aggregator本身也做为一个Maven项目,它必须有自己的POM
- 它的打包方式必须为:pom
- 版本:聚合模块的版本和被聚合模块版本一致
- relative path:每个module的值都是一个当前POM的相对目录
- 目录名称:为了方便的快速定位内容,模块所处的目录应当与其artifactId一致(Maven约定而不是硬性要求),总之,模块所处的目录必须和
模块所处的目录 相一致。 - 习惯约定:为了方便构建,通常将聚合模块放在项目目录层的最顶层,其它聚合模块作为子目录存在。这样当我们打开项目的时候,第一个看到的就是聚合模块的POM
- 聚合模块减少的内容:聚合模块的内容仅仅是一个pom.xml文件,它不包含src/main/java、src/test/java等目录,因为它只是用来帮助其它模块构建的工具,本身并没有实质的内容。
- 聚合模块和子模块的目录:他们可以是父子类,也可以是平行结构,当然如果使用平行结构,那么聚合模块的POM也需要做出相应的更改。
继承解决什么问题?
当多个模板的POM有相同的配置,可以抽离出重复的配置,减少重复。
1 | <modelVersion>4.0.0</modelVersion> |
可被继承的有:
- groupId:项目组ID,项目坐标的核心元素
- version: 项目版本, 项目坐标的核心元素
- description: 项目的描述信息
- organization: 项目的组织信息
- inceptionYear: 项目的创始年份
- url: 项目的URL地址
- developers: 项目开发者信息
- contributors: 项目的贡献者信息
- distributionManagement: 项目的部署配置
- issueManagement: 项目的缺陷跟踪系统信息
- ciManagement: 项目的持续集成系统信息
- scm: 项目的版本控制系统信息
- mailingLists: 项目的邮件列表信息
- properties: 自定义的maven属性
- dependencies: 项目的依赖配置
- dependencyManagement: 项目的依赖管理配置
- repositories: 项目的仓库配置
- build: 包括项目的源码目录配置、输出目录配置、插件配置、插件管理配置等
- reporting: 包括项目的报告输出目录配置、报告插件配置等
依赖管理
dependencies是可以被继承的,这个时候我们就想到让我们的发生了共用的依赖元素转移到parent中,这样我们又进一步的优化了配置。可是问题也随之而来,如果有一天我创建了一个新的模块,但是这个模块不需要这些parent的依赖,这时候如何处理?
dependencyManagement元素可以解决这个问题:在dependencyManagement中配置的元素既不会给parent引入依赖,也不会给它的子模块引入依赖,仅仅是它的配置是可继承的
1 | <!-- 父pom --> |
这样做似乎还是有重复的配置,但是可以有效的避免多个子模块使用依赖版本不一致的情况,有助于降低依赖冲突的几率。
插件的管理同样有pluginManagement元素
聚合POM和父POM没有要求是同一个POM,但是一般采用同一个
约定大于配置
在Maven中,约定大于配置:
- 默认源码目录为src/main/java
- 默认的源资源目录src/main/resource
- 默认测试源码目录为src/test/java
- 默认的测试资源目录src/test/resource
- 默认编译输出为target/classes/
- 默认打包方式为jar
- 默认包输出目录为target/
如果想要自定义源码目录:1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26<build>
<!--修改源代码目录 -->
<sourceDirectory>${project.build.directory}/src/main/java</sourceDirectory>
<outputDirectory>${project.build.directory}/target/classes/</outputDirectory> <!-- ${project.build.directory}就是我们通常看到的target目录 -->
<!--修改测试源代码目录 -->
<testSourceDirectory>${project.build.directory}/src/test/java </testSourceDirectory>
<testOutputDirectory>${project.build.directory}/target/test-classes</testOutputDirectory>
<!--修改资源目录 -->
<resources>
<resource>
<directory>${project.build.directory}/src/main/resource</directory>
<excludes>
<exclude>**/*.java</exclude>
</excludes>
</resource>
</resources>
<!--修改测试资源目录 -->
<testResources>
<testResource>
<directory>${project.build.directory}/src/test/resource</directory>
<excludes>
<exclude>**/*.java</exclude>
</excludes>
</testResource>
</testResources>
</build>
默认的包结构定义在超级POM中
反应堆
在多模块的Maven项目中,反应堆指所有模块组成的一个构建结构,包含了各模块之间的继承与依赖关系,从而能够自动计算出合理的模块构建顺序。
反应堆的建构顺序规则:
Maven按序杜旭POM,如果该POM没有依赖模块,那么构建该模块,否则就先构建其依赖模块,如果该依赖还依赖于其他模块,则进一步先构建依赖的依赖。
依赖关系会将反应堆构成一个有向非循环图,或出现循环,会报错。
反应堆裁剪(部分模块构建):
- -pl:构建指定模块,逗号分隔
- -rf:构建反应堆顺序中指定模块之后的所有模块
- -am:同时构建所列模块以及其依赖的模块
- -amd:同时构建所列模块以及依赖其的模块