0%

maven | 多模块配置

maven 多模块之间 pom 的配置。

将一个项目进行功能化拆分,后续方便使用微服务。

搭建多模块项目,需要使用 maven 的继承和聚合,其中聚合负责将多个模块集中在一起进行管理,继承则负责各子模块中的公共配置。

在我们项目顶层的 POM 文件中,我们会看到 dependencyManagement 元素。通过它元素来管理jar包的版本,让子项目中引用一个依赖而不用显示的列出版本号。

Maven会沿着父子层次向上走,直到找到一个拥有dependencyManagement元素的项目,然后它就会使用在这个dependencyManagement元素中指定的版本号。

统一管理项目的版本号,确保应用的各个项目的依赖和版本一致,才能保证测试的和发布的是相同的成果,因此,在顶层pom中定义共同的依赖关系。

同时可以避免在每个使用的子项目中都声明一个版本号,这样想升级或者切换到另一个版本时,只需要在父类容器里更新,不需要任何一个子项目的修改。

如果某个子项目需要另外一个版本号时,只需要在dependencies中声明一个版本号即可。子类就会使用子类声明的版本号,不继承于父类版本号。

dependencies即使在子项目中不写该依赖项,那么子项目仍然会从父项目中继承该依赖项(全部继承)

dependencyManagement里只是声明依赖,并不实现引入,因此子项目需要显示的声明需要用的依赖。

如果不在子项目中声明依赖,是不会从父项目中继承下来的;只有在子项目中写了该依赖项,并且没有指定具体版本,才会从父项目中继承该项,并且versionscope都读取自父pom

另外如果子项目中指定了版本号,那么会使用子项目中指定的jar版本。

要特别牢记,dependencyManagement 只是声明,并不引入。

单独的项目 pom

先看一个单独项目的 pom

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
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
<?xml version="1.0" encoding="UTF-8"?>
<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 https://maven.apache.org/xsd/maven-4.0.0.xsd">
<modelVersion>4.0.0</modelVersion>
<parent>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-parent</artifactId>
<version>2.7.5</version>
<relativePath/> <!-- lookup parent from repository -->
</parent>
<groupId>com.rhino</groupId>
<artifactId>analysis</artifactId>
<version>0.0.1-SNAPSHOT</version>
<name>analysis</name>
<description>Demo project for Spring Boot</description>
<properties>
<java.version>14</java.version>
</properties>
<dependencies>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter</artifactId>
</dependency>

<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-web</artifactId>
</dependency>

<dependency>
<groupId>org.projectlombok</groupId>
<artifactId>lombok</artifactId>
<optional>true</optional>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-test</artifactId>
<scope>test</scope>
</dependency>
</dependencies>

<build>
<plugins>
<plugin>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-maven-plugin</artifactId>
<configuration>
<excludes>
<exclude>
<groupId>org.projectlombok</groupId>
<artifactId>lombok</artifactId>
</exclude>
</excludes>
</configuration>
</plugin>
</plugins>
</build>

</project>

多模块项目

创建

目录结构如下

1
2
3
4
- modules
- module
- pom.xml
- pom.xml

其中 projectmodule 都是 maven 项目。

创建 maven 要如图中所示。

这个时候,我们看 modulespom.xml 的情况

1
2
3
4
5
6
7
8
9
10
11
12
13
14
<?xml version="1.0" encoding="UTF-8"?>
<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/xsd/maven-4.0.0.xsd">
<modelVersion>4.0.0</modelVersion>

<groupId>org.example</groupId>
<artifactId>modules</artifactId>
<packaging>pom</packaging>
<version>1.0-SNAPSHOT</version>
<modules>
<module>module</module>
</modules>
</project>

其多了一个

1
2
3
4
5
<packaging>pom</packaging>
<version>1.0-SNAPSHOT</version>
<modules>
<module>module</module>
</modules>

pom 是最简单的打包类型。不像 jarwar,它生成的构件只有它本身。将 packaging 申明为 pom 则意味着没有代码需要测试或者编译,也没有资源需要处理。

由于我们使用了聚合,所以打包方式必须为 pom ,否则无法构建。

module 的值是子模块相对于当前 POM 的路径。

接下来看子模块的 pom.xml

1
2
3
4
5
6
7
8
9
10
11
12
13
<?xml version="1.0" encoding="UTF-8"?>
<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/xsd/maven-4.0.0.xsd">
<parent>
<artifactId>modules</artifactId>
<groupId>org.example</groupId>
<version>1.0-SNAPSHOT</version>
</parent>
<modelVersion>4.0.0</modelVersion>

<artifactId>module</artifactId>
</project>

其有一处

1
2
3
4
5
<parent>
<artifactId>modules</artifactId>
<groupId>org.example</groupId>
<version>1.0-SNAPSHOT</version>
</parent>

声明了该模块继承自 org.example:modules:1.0-SNAPSHOT,其实这里面还省略了<relativePath></relativePath> 由于 relativePath 默认是 ../pom.xml 而我们的子项目确实在父项目的下一级目录中,所以是可以不用填写的。

Maven首先在当前构建项目的环境中查找父pom,然后项目所在的文件系统查找,然后是本地存储库,最后是远程repo。

artifactId 是子模块的组件 id,由于继承了父pom,所以groupIdversion 也可以不写,不写的话就默认继承自父pom

子模块间的依赖

如果子模块间相互依赖,需要在 dependency 中引入要依赖的子模块,如图

module2 中的 pom.xml 文件内容如下

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
<?xml version="1.0" encoding="UTF-8"?>
<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/xsd/maven-4.0.0.xsd">
<parent>
<artifactId>modules</artifactId>
<groupId>org.example</groupId>
<version>1.0-SNAPSHOT</version>
</parent>
<modelVersion>4.0.0</modelVersion>

<artifactId>module2</artifactId>

<dependencies>
<dependency>
<groupId>org.example</groupId>
<artifactId>module1</artifactId>
<version>1.0-SNAPSHOT</version>
</dependency>
</dependencies>

</project>

我们可以看到其依赖于 module1,但是,也写了版本,想象一下,如果 module1 更新了版本,module2pom.xml 也需要变化,如果,还有 module3 同样依赖于 module1 的话,那后续修改起来就非常麻烦了。

所以,我们将各个模块的版本放在父项目的 pom.xml 中。

内容改成了

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
27
28
29
<?xml version="1.0" encoding="UTF-8"?>
<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/xsd/maven-4.0.0.xsd">
<modelVersion>4.0.0</modelVersion>

<groupId>org.example</groupId>
<artifactId>modules</artifactId>
<packaging>pom</packaging>
<version>1.0-SNAPSHOT</version>
<modules>
<module>module2</module>
<module>module1</module>
</modules>

<properties>
<module1.version>1.0-SNAPSHOT</module1.version>
</properties>

<dependencyManagement>
<dependencies>
<dependency>
<groupId>org.example</groupId>
<artifactId>module2</artifactId>
<version>${module1.version}</version>
</dependency>
</dependencies>
</dependencyManagement>
</project>

我们就可以把 module2pom.xml 中的 module1version 给删掉了。

请我喝杯咖啡吧~