maven
多模块之间 pom
的配置。
将一个项目进行功能化拆分,后续方便使用微服务。
搭建多模块项目,需要使用 maven
的继承和聚合,其中聚合负责将多个模块集中在一起进行管理,继承则负责各子模块中的公共配置。
在我们项目顶层的 POM
文件中,我们会看到 dependencyManagement
元素。通过它元素来管理jar
包的版本,让子项目中引用一个依赖而不用显示的列出版本号。
Maven
会沿着父子层次向上走,直到找到一个拥有dependencyManagement
元素的项目,然后它就会使用在这个dependencyManagement
元素中指定的版本号。
统一管理项目的版本号,确保应用的各个项目的依赖和版本一致,才能保证测试的和发布的是相同的成果,因此,在顶层pom
中定义共同的依赖关系。
同时可以避免在每个使用的子项目中都声明一个版本号,这样想升级或者切换到另一个版本时,只需要在父类容器里更新,不需要任何一个子项目的修改。
如果某个子项目需要另外一个版本号时,只需要在dependencies
中声明一个版本号即可。子类就会使用子类声明的版本号,不继承于父类版本号。
dependencies
即使在子项目中不写该依赖项,那么子项目仍然会从父项目中继承该依赖项(全部继承)
dependencyManagement
里只是声明依赖,并不实现引入,因此子项目需要显示的声明需要用的依赖。
如果不在子项目中声明依赖,是不会从父项目中继承下来的;只有在子项目中写了该依赖项,并且没有指定具体版本,才会从父项目中继承该项,并且version
和scope
都读取自父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/> </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
|
其中 project
和 module
都是 maven
项目。
创建 maven
要如图中所示。
这个时候,我们看 modules
的 pom.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
是最简单的打包类型。不像 jar
和 war
,它生成的构件只有它本身。将 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
,所以groupId
、version
也可以不写,不写的话就默认继承自父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
更新了版本,module2
的 pom.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>
|
我们就可以把 module2
中 pom.xml
中的 module1
的 version
给删掉了。