1. 什么是继承

Maven 的依赖传递机制可以一定程度上简化 POM 的配置,但这仅限于存在依赖关系的项目或模块中。当一个项目的多个模块都依赖于相同 jar 包的相同版本,且这些模块之间不存在依赖关系,这就导致同一个依赖需要在多个模块中重复声明,这显然是不可取的,大量的前人经验告诉我们,重复往往意味着更多的劳动和更高的潜在风险。

image

在 Java 面向对象中,我们可以建立一种类的父子结构,然后在父类中声明一些字段和方法供子类继承,这样就可以一定程度上消除重复,做到 “一处声明,多处使用”。在 Maven 的世界中,也有类似的机制,它就是 POM 继承。

Maven 在设计时,借鉴了 Java 面向对象中的继承思想,提出了 POM 继承思想。当一个项目包含多个模块时,可以在该项目中再创建一个父模块,并在其 POM 中声明依赖,其他模块的 POM 可通过继承父模块的 POM 来获得对相关依赖的声明。

对于父模块而言,其目的是为了消除子模块 POM 中的重复配置,其中不包含有任何实际代码,因此父模块 POM 的打包类型(packaging)必须是 pom。

如图所示:

image

子工程可以继承的父工程的元素:

元素 描述
groupId 项目组 ID,项目坐标的核心元素
version 项目版本,项目坐标的核心元素
description 项目的描述信息
organization 项目的组织信息
inceptionYear 项目的创始年份
url 项目的 URL 地址
developers 项目的开发者信息
contributors 项目的贡献者信息
distributionManagement 项目的部署配置
issueManagement 项目的缺陷跟踪系统信息
ciManagement 项目的持续集成系统信息
scm 项目的版本控制系统信息
mailingLists 项目的邮件列表信息
properties 自定义的 Maven 属性
dependencies 项目的依赖配置
dependencyManagement 项目的依赖管理配置
repositories 项目的仓库配置
build 包括项目的源码目录配置、输出目录配置、插件配置、插件管理配置等
reporting 包括项目的报告输出目录配置、报告插件配置等

总结:一句话,通过继承可以实现子工程沿用父工程的配置。大大减少重复设置。

父工程示例:

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
<modelVersion>4.0.0</modelVersion>
<groupId>com.bjpowernode</groupId>
<artifactId>maven_parent</artifactId>
<version>1.0-SNAPSHOT</version>
<!--打包方式必须是pom,声明是父工程-->
<packaging>pom</packaging>

<!--聚合子模块-->
<modules>
<module>maven_son</module>
<module>maven_web</module>
</modules>

<properties>
<!--定义属性,便于版本的管理-->
<spring-version>5.3.24</spring-version>
<servlet-version>4.0.1</servlet-version>
</properties>

<!--只是定义,并没有真正的添加依赖,子工程根据需要有选择的添加依赖-->
<dependencyManagement>
<dependencies>
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-context</artifactId>
<!--引用定义好的属性-->
<version>${spring-version}</version>
</dependency>
<dependency>
<groupId>javax.servlet</groupId>
<artifactId>javax.servlet-api</artifactId>
<version>${servlet-version}</version>
<scope>provided</scope>
</dependency>
</dependencies>
</dependencyManagement>

<build>
<pluginManagement>
<plugins>
<!--只定义Tomcat插件 -->
<plugin>
<groupId>org.apache.tomcat.maven</groupId>
<artifactId>tomcat7-maven-plugin</artifactId>
<version>2.2</version>
<configuration>
<port>8089</port>
<url>/</url>
</configuration>
</plugin>
</plugins>
</pluginManagement>
</build>

子工程示例:

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
<modelVersion>4.0.0</modelVersion>
<parent>
<groupId>com.bjpowernode</groupId>
<artifactId>maven_parent</artifactId>
<version>1.0-SNAPSHOT</version>
</parent>
<!--可以省略groupId和version,因为与父工程保持一致-->
<artifactId>maven_web</artifactId>
<packaging>war</packaging>

<!--需要什么依赖,添加什么依赖,可以省略版本号,版本由父工程统一管理 -->
<dependencies>
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-context</artifactId>
</dependency>
<dependency>
<groupId>javax.servlet</groupId>
<artifactId>javax.servlet-api</artifactId>
</dependency>
</dependencies>

<build>
<plugins>
<!--配置Tomcat插件 -->
<plugin>
<groupId>org.apache.tomcat.maven</groupId>
<artifactId>tomcat7-maven-plugin</artifactId>
<version>2.2</version>
<!--子工程可以自定义端口号,不自定义使用父工程的-->
<configuration>
<port>8060</port>
<url>/</url>
</configuration>
</plugin>
</plugins>
</build>

总结:一句话,通过继承可以实现子工程沿用父工程的配置。大大减少重复设置。

2. 什么是聚合

使用 Maven 聚合功能对项目进行构建时,需要在该项目中额外创建一个的聚合模块,然后通过这个模块构建整个项目的所有模块。聚合模块仅仅是帮助聚合其他模块的工具,其本身并无任何实质内容,因此聚合模块中只有一个 POM 文件,不包含 src 等目录。

与父模块相似, 聚合模块的打包方式(packaging)也是 pom,用户可以在其 POM 中通过 modules 下的 module 子元素来添加需要聚合的模块的目录路径。父模块的 pom.xml 文件的 把子模块聚集起来.

项目结构:

image

总结:一句话,聚合就是集中构建项目的。