一、创建父工程
创建的过程和前面创建普通工程 一样。
工程名称:pro03-maven-parent
工程创建好之后,要修改它的打包方式:
1
2
3
4
5
6
| <groupId>com.atguigu.maven</groupId>
<artifactId>pro03-maven-parent</artifactId>
<version>1.0-SNAPSHOT</version>
<!-- 当前工程作为父工程,它要去管理子工程,所以打包方式必须是 pom -->
<packaging>pom</packaging>
|
有打包方式为 pom 的 Maven 工程能够管理其他 Maven 工程。打包方式为 pom 的 Maven 工程中不写业务代码,它是专门管理其他 Maven 工程的工程。
二、创建模块工程
模块工程类似于 IDEA 中的 module,所以需要进入 pro03-maven-parent 工程的根目录,然后运行 mvn archetype:generate 命令来创建模块工程。
假设,我们创建三个模块工程:
三、查看被添加新内容的父工程 pom.xml
下面 modules 和 module 标签是聚合功能的配置
1
2
3
4
5
| <modules>
<module>pro04-maven-module</module>
<module>pro05-maven-module</module>
<module>pro06-maven-module</module>
</modules>
|
四、解读子工程的pom.xml
1
2
3
4
5
6
7
8
9
10
11
12
13
| <!-- 使用parent标签指定当前工程的父工程 -->
<parent>
<!-- 父工程的坐标 -->
<groupId>com.atguigu.maven</groupId>
<artifactId>pro03-maven-parent</artifactId>
<version>1.0-SNAPSHOT</version>
</parent>
<!-- 子工程的坐标 -->
<!-- 如果子工程坐标中的groupId和version与父工程一致,那么可以省略 -->
<!-- <groupId>com.atguigu.maven</groupId> -->
<artifactId>pro04-maven-module</artifactId>
<!-- <version>1.0-SNAPSHOT</version> -->
|
五、在父工程中配置依赖的统一管理
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
| <!-- 使用dependencyManagement标签配置对依赖的管理 -->
<!-- 被管理的依赖并没有真正被引入到工程 -->
<dependencyManagement>
<dependencies>
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-core</artifactId>
<version>4.0.0.RELEASE</version>
</dependency>
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-beans</artifactId>
<version>4.0.0.RELEASE</version>
</dependency>
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-context</artifactId>
<version>4.0.0.RELEASE</version>
</dependency>
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-expression</artifactId>
<version>4.0.0.RELEASE</version>
</dependency>
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-aop</artifactId>
<version>4.0.0.RELEASE</version>
</dependency>
</dependencies>
</dependencyManagement>
|
六、子工程中引用那些被父工程管理的依赖
关键点:省略版本号
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
| <!-- 把版本号去掉就表示子工程中这个依赖的版本由父工程决定。 -->
<!-- 具体来说是由父工程的dependencyManagement来决定。 -->
<dependencies>
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-core</artifactId>
</dependency>
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-beans</artifactId>
</dependency>
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-context</artifactId>
</dependency>
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-expression</artifactId>
</dependency>
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-aop</artifactId>
</dependency>
</dependencies>
|
七、在父工程中声明自定义属性
1
2
3
4
5
6
7
| <properties>
<project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
<!-- 自定义标签,维护Spring版本数据 -->
<!-- 通过自定义属性,统一指定Spring的版本 -->
<atguigu.spring.version>4.3.6.RELEASE</atguigu.spring.version>
</properties>
|
在需要的地方使用${}的形式来引用自定义的属性名:
1
2
3
4
5
| <dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-core</artifactId>
<version>${atguigu.spring.version}</version>
</dependency>
|
真正实现“一处修改,处处生效”。
八、实际意义
编写一套符合要求、开发各种功能都能正常工作的依赖组合并不容易。如果公司里已经有人总结了成熟的组合方案,那么再开发新项目时,如果不使用原有的积累,而是重新摸索,会浪费大量的时间。为了提高效率,我们可以使用工程继承的机制,让成熟的依赖组合方案能够保留下来。
如上图所示,公司级的父工程中管理的就是成熟的依赖组合方案,各个新项目、子系统各取所需即可。
实验 多重继承:
1、aaa项目:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
| <groupId>org.example</groupId>
<artifactId>aaa</artifactId>
<version>1.0-SNAPSHOT</version>
<packaging>pom</packaging>
<dependencyManagement>
<dependencies>
<dependency>
<groupId>org.javassist</groupId>
<artifactId>javassist</artifactId>
<version>3.24.1-GA</version>
</dependency>
<dependency>
<groupId>com.google.guava</groupId>
<artifactId>guava</artifactId>
<version>24.0-jre</version>
</dependency>
</dependencies>
</dependencyManagement>
|
2、bbb项目继承aaa项目:
重新定义 javassist的版本
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
| <parent>
<groupId>org.example</groupId>
<artifactId>aaa</artifactId>
<version>1.0-SNAPSHOT</version>
</parent>
<modelVersion>4.0.0</modelVersion>
<artifactId>bbb</artifactId>
<packaging>pom</packaging>
<dependencyManagement>
<dependencies>
<dependency>
<groupId>org.javassist</groupId>
<artifactId>javassist</artifactId>
<version>3.28.0-GA</version>
</dependency>
</dependencies>
</dependencyManagement>
|
3、ccc项目继承bbb项目:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
| <parent>
<groupId>org.example</groupId>
<artifactId>bbb</artifactId>
<version>1.0-SNAPSHOT</version>
</parent>
<modelVersion>4.0.0</modelVersion>
<artifactId>ccc</artifactId>
<dependencies>
<dependency>
<groupId>org.javassist</groupId>
<artifactId>javassist</artifactId>
</dependency>
<dependency>
<groupId>com.google.guava</groupId>
<artifactId>guava</artifactId>
</dependency>
</dependencies>
|
4、发现
这时 执行 mvn dependency:tree 发现:
1、javassist的版本是bbb项目定义的版本,被覆盖了;
2、guava的版本还是aaa项目的版本;
3、并且当修改aaa项目的guava版本,aaa项目内 mvn install 后,在ccc项目中重新加载后,发现guava版本也随之更改,这时就跟bbb项目的状态无关。
tip:
在bbb项目虽然是pom的打包格式,但是也可以写dependencies,直接依赖jar包,和dependencyManagement分别做两件事,不会出错