使用Maven构建多模块项目

Multi-Module Project with Maven

[author[source]] [https://www.baeldung.com/maven-multi-module] [Multi-Module Project with Maven]

1.概览

在这个教程中,我们将学习maven的多模块项目构建。首先讨论什么是多模块项目,了解多模块的优点。然后尝试搭建一个样板多模块项目。

2.Maven多模块项目

一个多模块项目是通过聚合pom来构建的。聚合pom管理多个子模块。大多数情况下,聚合pom在项目的根目录。打包方式必须是pom

子模块就是maven常规项目,他们可以分别进行构建或者通过聚合pom一起构建。通过聚合pom构建项目,每个模块最终会输出不同的打包文件。

3.使用多模块的好处

使用多模块构建项目的优点之一就是减少重复。假设一个项目有多个模块,我们改变功能之后,如果没有特定的构建工具,我们就必须分别对模块进行构建,或者写个脚本来编译他们的代码、测试、展示结果。当我们项目中的模块越来越多后,将越来越难维护。在实际的使用过程中,我们的项目需要使用maven插件在项目构建生命周期当中执行不同的操作,例如共享依赖和配置,导入其他的

项目。

因此在使用多模块的时候我们可以通过一行命令来构建我们的应用,并且maven会自动识别模块的构建顺序,我们同样可以在其他模块中重复使用配置信息。

4.Parent POM

Maven 的pom文件支持继承 父pom,两个pom会被合并成一个有效的pom文件。我们可以创建自己的pom 文件 作为我们的父项目。然后在这个父项目的pom文件中我们可以加入所有的依赖配置。 将这个pom文件作为子模块的父pom,从而继承这些配置。这种pom就称作聚合pom,并且声明了子模块。

5.子模块

子模块都是继承自 父 POM, 继承可以使子模块分享依赖和配置,如果我们想一次性地构建或发布我们的项目,则必须在父型POM中明确声明我们的子模型。

6.构建多模块项目

下面构建的应用包含3个模块

  • core 核心domain模块
  • web service 提供 restful api
  • webapp

6.1.生成parent pom

1
mvn archetype:generate -DgroupId=com.baeldung -DartifactId=parent-project

pom文件生成之后修改pom文件打包方式为 pom

1
<packaging>pom</packaging>

这样我们就定义了一个聚合项目,在这个pom文件中我们可以编辑dependencyManagement ,和pluginManagement ,这些配置可以被子项目重复使用。

6.2.创建子项目

确保进入父项目目录后执行以下命令生成子项目。

1
2
3
4
cd parent-project
mvn archetype:generate -DgroupId=com.baeldung -DartifactId=core
mvn archetype:generate -DgroupId=com.baeldung -DartifactId=service
mvn archetype:generate -DgroupId=com.baeldung -DartifactId=webapp

执行完成之后在父项目中的pom文件当中会增加模块描述信息

1
2
3
4
5
<modules>
<module>core</module>
<module>service</module>
<module>webapp</module>
</modules>

在各个子项目中会增加父项目的依赖信息

1
2
3
4
5
<parent>
<artifactId>parent-project</artifactId>
<groupId>com.baeldung</groupId>
<version>1.0-SNAPSHOT</version>
</parent>

需要注意的是每个子项目只能有一个父项目,但是我们可以通过 import的方式导入 多个 BOM (bill of material)

bom 简单理解就是控制项目版本和依赖的pom,引入这个pom是为了保证依赖不会出现问题。

https://www.baeldung.com/spring-maven-bom

6.3.构建项目

在父项目目录下运行

1
mvn package

这将会构建所有模块

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
[INFO] Scanning for projects...
[INFO] ------------------------------------------------------------------------
[INFO] Reactor Build Order:
[INFO] parent-project [pom]
[INFO] core [jar]
[INFO] service [jar]
[INFO] webapp [war]
...
[INFO] Reactor Summary for parent-project 1.0-SNAPSHOT:
[INFO] parent-project ..................................... SUCCESS [ 0.272 s]
[INFO] core ............................................... SUCCESS [ 2.043 s]
[INFO] service ............................................ SUCCESS [ 0.627 s]
[INFO] webapp ............................................. SUCCESS [ 0.572 s]
[INFO] ------------------------------------------------------------------------
[INFO] BUILD SUCCESS
[INFO] ------------------------------------------------------------------------

输出中可以看到,三个子模块分别输出了给自的产物,由于父项目 是pom 所以没有产物输出。如果 webapp模块依赖 service模块 maven 会优先构建service模块

6.3.在parent pom 中使用 依赖管理

依赖管理是一种将多模块父母项目及其子女的依赖信息集中的机制。当您有一组继承共同父母的项目或模块时,您可以将有关依赖项的所有必需信息放在common pom.xml文件中。这将简化子项目POM中的依赖的引用。

parent pom.xml

1
2
3
4
5
6
7
8
9
10
<dependencyManagement>
<dependencies>
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-core</artifactId>
<version>5.3.16</version>
</dependency>
//...
</dependencies>
</dependencyManagement>

在父项目中定义了spring-core的坐标和版本信息之后,在子项目中只需要定义 groupId 和 artifactId 信息,version信息将被继承。

此外可以增加排除依赖的信息,这样排除的依赖将不会被子模块继承

1
2
3
4
5
6
<exclusions>
<exclusion>
<groupId>org.springframework</groupId>
<artifactId>spring-context</artifactId>
</exclusion>
</exclusions>

如果子模块需要使用不同版本的依赖,可以在子项目的pom文件中指定版本信息,覆盖从父pom所继承的版本信息

1
2
3
4
5
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-core</artifactId>
<version>4.3.30.RELEASE</version>
</dependency>

请注意 聚合pom文件可以包含没有继承子他的子项目

参考链接: https://maven.apache.org/pom.html#Aggregation

6.4.更新子模块pom配置,并构建项目

把webapp子模块的package 改成 war 并加入 war的打包插件

1
2
3
4
5
6
7
8
9
10
11
12
<build>
<plugins>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-war-plugin</artifactId>
<version>3.3.2</version>
<configuration>
<failOnMissingWebXml>false</failOnMissingWebXml>
</configuration>
</plugin>
</plugins>
</build>

执行 mvn install

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
[INFO] Scanning for projects...
[INFO] ------------------------------------------------------------------------
[INFO] Reactor Build Order:
[INFO]
[INFO] parent-project [pom]
[INFO] core [jar]
[INFO] service [jar]
[INFO] webapp [war]
//.............
[INFO] Reactor Summary for parent-project 1.0-SNAPSHOT:
[INFO]
[INFO] parent-project ..................................... SUCCESS [ 0.272 s]
[INFO] core ............................................... SUCCESS [ 2.043 s]
[INFO] service ............................................ SUCCESS [ 0.627 s]
[INFO] webapp ............................................. SUCCESS [ 1.047 s]

7.结论

这篇文章讨论了多模块的优点,并且区分了聚合pom和普通pom,最后也探索了如何搭建一个多模块项目。

maven很有用,但是也很复杂,如果需要深入学习可以查看以下链接

如果想了解maven 多模块的高级用法可以查阅