maven 继承和聚合
目录
- 聚合
1.1 为啥需要分模块开发?
1.2 为啥需要聚合?
1.3 如何使用聚合?
1.4 实际方案(方案一、二)
1.5 反应堆(构建顺序和命令) - 继承
2.1 为啥需要继承?
2.2 如何继承?
2.2 继承哪些重要参数? - 聚合和继承的区别
- maven的约定(超级pom)
1. 聚合
1.1 为啥需要分模块开发?
其实就我个人而言,就是为了重复利用代码
- 减少bulid时间,只需要bulid需要的模块
- 一定程度上代码复用(但请不要刻意追求)
- 方便不同的人开发不同的模块。
- 减少依赖冗余,明确不同模块需要的依赖
1.2 为啥需要聚合?
因为分模块了,所以需要用某种方式统一起来
分模块开发有一个很大的问题,我想将全部模块统一打包mvn package
,如果没有聚合的话,我需要对每一个模块分别执行mvn package
,同时我还要确定执行顺序,及其繁琐!
1.3 聚合的使用
聚合的本质,通过一个模块去关联其他模块
首先必须有一个专门用于聚合的模块,他的主要作用是:(反应堆)
- 确定聚合模块
我们通过modules中的module来确定需要聚合的模块。 - 分析聚合顺序
通过反应堆(reactor)来明确顺序。 - 执行相关命令
通过在该pom.xml目录下执行命令,来对全部项目执行命令。
注意:
- 作为聚合的项目的packaging必须为pom类型
- module的值 为当前pom.xml的相对目录
- 通常聚合模块作为项目最顶层
1.4 实际方案
方案一:(聚合模块作为最顶层项目)
1.项目结构
---- app-parent
|-- pom.xml (pom)
|
|-- app-util
| |-- pom.xml (jar)
|
|-- app-web
|-- pom.xml (war)
2.聚合项目 pom.xml
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/maven-v4_0_0.xsd">
<modelVersion>4.0.0</modelVersion>
<groupId>org.xx</groupId>
<artifactId>app-parent</artifactId>
<packaging>pom</packaging>
<version>1.0-SNAPSHOT</version>
<modules>
<module>app-util</module>
<module>app-web</module>
</modules>
</project>
方案二:(聚合模块与被聚合项目属于平层)
1.项目结构
|-- app-parent
| |-- pom.xml (pom)
|
|-- app-util
| |-- pom.xml (jar)
|
|-- app-web
| |-- pom.xml (war)
2.聚合项目 pom.xml
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/maven-v4_0_0.xsd">
<modelVersion>4.0.0</modelVersion>
<groupId>org.xxx</groupId>
<artifactId>app-parent</artifactId>
<packaging>pom</packaging>
<version>1.0-SNAPSHOT</version>
<modules>
<module>../app-util</module>
<module>../app-web</module>
</modules>
</project>
1.5 反应堆
反应堆是针对聚合而言,对于聚合模块而言,反应堆就是各个module
1.5.1 反应堆的构建顺序
module顺序:(其中A依赖B)
<modules>
<module>moduleA</module>
<module>moduleB</module>
<module>moduleC</module>
</modules>
构建:
- 首先会按照顺序找到第一个module的pom,moduleA,分析其中依赖,发现moduleA依赖moduleB,那么继续分析moduleB,发现没有依赖任何一个module,那么首先构建moduleB,然后构建moduleA。
- 接着继续按照顺序查找,找到moduleB,发现其已经被构建,故不再构建。
- 接着继续按照顺序查找,找到moduleC,发现其未构建,且未依赖其他module,那么构建moduleC
1.5.2 反应堆的命令
-am,--also-make:同时构建所列模块的依赖模块
-amd,-also-make-dependents:同时构建依赖于所列模块的模块
-pl,--projects<arg>:构建指定的模块,模块间用逗号分隔
-rf,-resume-from<arg>:在完整的反应堆构建顺序基础上指定从哪个模块开始构建
2. 继承
2.1 为啥需要继承?
一言以蔽之,全部的继承都是为了减少重复代码
- 可以减少sub pom.xml中的配置文件。
- 可以在某种程度管理sub pom.xml,比如 dependencyManagement,plugManagement等
2.2 如何继承?
1.步骤
首先我们需要parent module,同时必须设置module packaging为pom类型,因为我们只能继承pom 而非代码。
其次我们需在要在sub module里面继承parent module
2.relativePath
a. relativePath如何进行解析
relativePath默认为../pom.xml 也就是说明 继承的默认结构为 父模块在子模块上
relativePath的查找顺序为:relativePath元素中的地址–本地仓库–远程仓库
设定一个空值将始终从仓库中获取,不从本地路径获取,如<relativePath />
b. 为什么说最好正确的设置 relativePath?
如果一个新的成员来到团队开发,checkout一个父子模块,由于主要关注子模块信息,这时候直接编译子模块可能会编译不成功,因为如果不写relativePath,那么先找的则是 ../pom.xml(默认),而项目父模块不一定正好是子模块的上层,而继续找本地仓库,而父模块可能没有install到本地仓库,而远程仓库也可能不存在父模块,从而导致子模块编译失败!
2.3 继承哪些重要参数?
1.group version:
方便统一 group version
2.dependencyManagement:
a.主要作用:
只是声明依赖,并不实现引入
申明了scope和version,子类可以覆盖
b. scope 为 import对dependencyManagement作用:
1.scope为import时,只有在dependencyManagement元素下才有用,且一般都是指向打包类型为pom的模块。
2.作用主要是:将目标pom中的dependencyManagement 导入合并到当前 dependencyManagement下。(具体咋合并的没研究过,实验过的朋友可以帮忙评论下)
- 实际案例(springboot):https://blog.csdn.net/rainbow702/article/details/55046298
3.pluginManagement
主要作用:
申明插件,但不引入插件。
子模块仅仅需要groupId和artifactId就可以引入插件以及插件相关配置
3.聚合和继承的区别
不同:
- 对于聚合模块而言,它知道我有哪些聚合模块,对于被聚合模块而言,它不知道聚合模块的存在。
- 对于继承的父模块来说,它不知道哪些子模块继承它,但那些子模块必须知道继承了哪些父模块。
相同:
聚合模块和父模块的packaging 都必须为pom类型。
4. maven的约定(超级pom)
谈到maven的约定就必须知道超级pom
- 超级pom就想java Object类一样,所有没有继承pom的模块都会默认会继承这个pom
- 一般都在
$MAVEN_HOME/lib/maven-model-builder-x.x.x.jar
内的org/apache/maven/model/
内的pom-4.0.0.xml
文件 ,由此我们也可以猜到 为啥每个pom都必须带上的<modelVersion>4.0.0</modelVersion>
我们通过 pom-4.0.0.xml 观察约定
<project>
<modelVersion>4.0.0</modelVersion> <!-- 很奇怪哟,他为啥也要modelVersion呢。。 modelVersion又不会继承 -->
<repositories> <!-- 子类会继承这个repository -->
<repository>
<id>central</id>
<name>Central Repository</name>
<url>https://repo.maven.apache.org/maven2</url>
<layout>default</layout>
<snapshots> <!-- 默认不会下载snapshots -->
<enabled>false</enabled>
</snapshots>
</repository>
</repositories>
<pluginRepositories> <!-- 子类同样会继承,但是我觉得没太大意义 -->
<pluginRepository>
<id>central</id>
<name>Central Repository</name>
<url>https://repo.maven.apache.org/maven2</url>
<layout>default</layout>
<snapshots>
<enabled>false</enabled>
</snapshots>
<releases>
<updatePolicy>never</updatePolicy>
</releases>
</pluginRepository>
</pluginRepositories>
<build>
<directory>${project.basedir}/target</directory><!-- -->
<outputDirectory>${project.build.directory}/classes</outputDirectory><!-- 生成类输出目录 -->
<finalName>${project.artifactId}-${project.version}</finalName><!-- 文件名 -->
<testOutputDirectory>${project.build.directory}/test-classes</testOutputDirectory>
<sourceDirectory>${project.basedir}/src/main/java</sourceDirectory>
<scriptSourceDirectory>${project.basedir}/src/main/scripts</scriptSourceDirectory>
<testSourceDirectory>${project.basedir}/src/test/java</testSourceDirectory>
<resources>
<resource>
<directory>${project.basedir}/src/main/resources</directory>
</resource>
</resources>
<testResources>
<testResource>
<directory>${project.basedir}/src/test/resources</directory>
</testResource>
</testResources>
<pluginManagement>
<!-- NOTE: These plugins will be removed from future versions of the super POM -->
<!-- 这些插件会在后面版本移除 -->
<!-- They are kept for the moment as they are very unlikely to conflict with lifecycle mappings (MNG-4453) -->
<plugins>
<plugin>
<artifactId>maven-antrun-plugin</artifactId>
<version>1.3</version>
</plugin>
<plugin>
<artifactId>maven-assembly-plugin</artifactId>
<version>2.2-beta-5</version>
</plugin>
<plugin>
<artifactId>maven-dependency-plugin</artifactId>
<version>2.8</version>
</plugin>
<plugin>
<artifactId>maven-release-plugin</artifactId>
<version>2.3.2</version>
</plugin>
</plugins>
</pluginManagement>
</build>
<reporting>
<outputDirectory>${project.build.directory}/site</outputDirectory>
</reporting>
<profiles>
<!-- NOTE: The release profile will be removed from future versions of the super POM -->
<profile>
<id>release-profile</id>
<activation>
<property>
<name>performRelease</name>
<value>true</value>
</property>
</activation>
<build>
<plugins>
<plugin>
<inherited>true</inherited>
<artifactId>maven-source-plugin</artifactId>
<executions>
<execution>
<id>attach-sources</id>
<goals>
<goal>jar</goal>
</goals>
</execution>
</executions>
</plugin>
<plugin>
<inherited>true</inherited>
<artifactId>maven-javadoc-plugin</artifactId>
<executions>
<execution>
<id>attach-javadocs</id>
<goals>
<goal>jar</goal>
</goals>
</execution>
</executions>
</plugin>
<plugin>
<inherited>true</inherited>
<artifactId>maven-deploy-plugin</artifactId>
<configuration>
<updateReleaseInfo>true</updateReleaseInfo>
</configuration>
</plugin>
</plugins>
</build>
</profile>
</profiles>
</project>