不同模块间有相同的 groupId,version ;有时候,也会需要引入相同的依赖。这个时候,如果每个模块都重复引入的话,结果就会造成冗余。作为一个遵循面向对象的程序员来讲,这样的做法显然是不合理的。
因此,Maven 也引入了类似的机制来解决这个问题,就是继承的特性。
例:
Project A
<project>
<modelVersion>4.0.0</modelVersion>
<groupId>com.mycompany.app</groupId>
<artifactId>my-app</artifactId>
<version>1</version>
</project>
Project B
<project>
<modelVersion>4.0.0</modelVersion>
<groupId>com.mycompany.app</groupId>
<artifactId>my-module</artifactId>
<version>1</version>
</project>
目录结构
|-- my-module
| `-- pom.xml
`-- pom.xml
注:my-module/pom.xml 是Project B的pom文件 。 pom.xml 是Project A的pom文件
现在修改Project B的pom文件,添加parent标签,就可以重用Project A里面的依赖,而无需B中重新定义使用到A的依赖
<project>
<modelVersion>4.0.0</modelVersion>
<parent>
<groupId>com.mycompany.app</groupId>
<artifactId>my-app</artifactId>
<version>1</version>
</parent>
<groupId>com.mycompany.app</groupId>
<artifactId>my-module</artifactId>
<version>1</version>
</project>
如果希望模块的 groupId或version与其父级相同,则可以在其 POM 中删除模块的 groupId或version。
<project>
<modelVersion>4.0.0</modelVersion>
<parent>
<groupId>com.mycompany.app</groupId>
<artifactId>my-app</artifactId>
<version>1</version>
</parent>
<artifactId>my-module</artifactId>
</project>
目录结构修改为下面所示
|-- my-module
| `-- pom.xml
`-- parent
`-- pom.xml
相应的Project B 进行如下修改即可
<project>
<modelVersion>4.0.0</modelVersion>
<parent>
<groupId>com.mycompany.app</groupId>
<artifactId>my-app</artifactId>
<version>1</version>
<relativePath>../parent/pom.xml</relativePath>
</parent>
<artifactId>my-module</artifactId>
</project>
dependencyManagement标签
Maven提供dependencyManagement标签既能让子模块继承父模块的依赖配置,又能保持子模块依赖使用的灵活性。在dependencyManagement标签下的依赖配置不会引入实际的依赖,不过他能够约束dependencies下的依赖使用。
<project>
...
<dependencyManagement>
<dependencies>
<dependency>
<groupId>group-a</groupId>
<artifactId>artifact-a</artifactId>
<version>1.0</version>
<exclusions>
<exclusion>
<groupId>group-c</groupId>
<artifactId>excluded-artifact</artifactId>
</exclusion>
</exclusions>
</dependency>
<dependency>
<groupId>group-c</groupId>
<artifactId>artifact-b</artifactId>
<version>1.0</version>
<type>war</type>
<scope>runtime</scope>
</dependency>
<dependency>
<groupId>group-a</groupId>
<artifactId>artifact-b</artifactId>
<version>1.0</version>
<type>bar</type>
<scope>runtime</scope>
</dependency>
</dependencies>
</dependencyManagement>
</project>
import依赖
在较大的项目中,由于项目只能从单个父级继承,因此可能无法实现此目的。为了适应这种情况,项目可以从其他项目导入托管依赖项。这是通过将 POM 的artifact 声明为作用域为“import”的依赖项来实现的。使用该范围的依赖通常指向一个POM,作用是将目标POM中的dependencyManagement配置导入合并到当前POM的dependencyManagement标签中
<!-- 可以集中定义依赖资源的版本信息 -->
<properties>
<spring-boot-version>2.3.5.RELEASE</spring-boot-version>
<spring-cloud-version>Hoxton.SR8</spring-cloud-version>
</properties>
<dependencyManagement>
<dependencies>
<!-- spring boot 依赖 -->
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-dependencies</artifactId>
<version>${spring-boot-version}</version>
<type>pom</type>
<scope>import</scope>
</dependency>
<!-- spring cloud 依赖 -->
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-dependencies</artifactId>
<version>${spring-cloud-version}</version>
<type>pom</type>
<scope>import</scope>
</dependency>
</dependencies>
</dependencyManagement>
项目聚合类似于项目继承。但是,它不是从模块指定父 POM,而是从父 POM 指定模块。通过这样做,父项目现在知道其模块,并且如果对父项目调用 Maven 命令,则该 Maven 命令也将执行到父项目的模块。若要执行项目聚合,必须执行以下操作:
|-- my-module
| -- pom.xml
-- pom.xml
Project A 和 Project B 聚合
如果我们要将 Project B聚合到Project A中,我们只需要修改Project A。
<project>
<modelVersion>4.0.0</modelVersion>
<groupId>com.mycompany.app</groupId>
<artifactId>my-app</artifactId>
<version>1</version>
<packaging>pom</packaging>
<modules>
<module>my-module</module>
</modules>
</project>
目录结构更改
|-- my-module
| `-- pom.xml
`-- parent
`-- pom.xml
修改后的Project A 的pom.xml
<project>
<modelVersion>4.0.0</modelVersion>
<groupId>com.mycompany.app</groupId>
<artifactId>my-app</artifactId>
<version>1</version>
<packaging>pom</packaging>
<modules>
<module>../my-module</module>
</modules>
</project>
如果您有多个 Maven 项目,并且它们都具有相似的配置,则可以通过提取这些类似的配置并创建父项目来重构项目。因此,您所要做的就是让您的 Maven 项目继承该父项目,然后将这些配置应用于所有这些项目。
如果您有一组一起生成或处理的项目,则可以创建一个父项目,并让该父项目将这些项目声明为其模块。通过这样做,你只需要构建父级,其余的就会随之而来。
但是,当然,您可以同时拥有项目继承和项目聚合。这意味着,您可以让模块指定父项目,同时让该父项目将这些 Maven 项目指定为其模块。您只需要应用所有三个规则:
修改后的Project A 的pom.xml
<project>
<modelVersion>4.0.0</modelVersion>
<groupId>com.mycompany.app</groupId>
<artifactId>my-app</artifactId>
<version>1</version>
<packaging>pom</packaging>
<modules>
<module>../my-module</module>
</modules>
</project>
修改后的Project B 的pom.xml
<project>
<modelVersion>4.0.0</modelVersion>
<parent>
<groupId>com.mycompany.app</groupId>
<artifactId>my-app</artifactId>
<version>1</version>
<relativePath>../parent/pom.xml</relativePath>
</parent>
<artifactId>my-module</artifactId>
</project>