在云原生和微服务架构下,一个大型系统往往被拆分为数十甚至上百个模块。如果每个模块都独立配置依赖、插件和版本,维护成本将呈指数级上升。Maven 提供了两大核心机制来解决这一问题:聚合(Aggregation)与继承(Inheritance)。
聚合是项目的“骨架”,负责将分散的模块组织在一起,实现一键构建。
继承是项目的“灵魂”,负责统一管理配置和依赖版本,消除重复劳动。
理解并熟练运用这两者,是构建标准化、可维护的大型 Maven 项目的基础。

聚合是指在一个父工程中,通过声明的方式将多个子模块(Modules)组合在一起。
核心作用:允许开发者在根目录下执行一次 Maven 命令(如 mvn clean install),Maven 就会自动按照正确的顺序编译、测试、打包所有子模块。
物理形态:聚合工程本身通常不包含任何 Java 源代码,它的 pom.xml 仅作为管理入口存在。

创建一个聚合工程非常简单,关键在于两个配置点:
父工程的 <packaging> 必须设置为 pom。这告诉 Maven:“我是一个容器,不生成 JAR 或 WAR 包”。
<project>
<modelVersion>4.0.0</modelVersion>
<groupId>com.example.cloud</groupId>
<artifactId>cloud-parent</artifactId>
<version>1.0.0-SNAPSHOT</version>
<!-- 关键点:打包类型必须为 pom -->
<packaging>pom</packaging>
<name>Cloud Native Parent</name>
</project>使用 <modules> 标签列出所有子模块的目录名(相对路径)。
<modules>
<!-- 对应目录:cloud-common -->
<module>cloud-common</module>
<!-- 对应目录:cloud-core -->
<module>cloud-core</module>
<!-- 对应目录:cloud-admin -->
<module>cloud-admin</module>
</modules>Maven 的聚合机制不仅仅是简单的循环执行。它会自动分析模块间的依赖关系,构建一个有向无环图,从而确定最佳构建顺序。
场景:如果 cloud-admin 依赖 cloud-core,而 cloud-core 依赖 cloud-common。
结果:即使你在 <modules> 中把 cloud-admin 写在第一个,Maven 也会自动先构建 cloud-common,然后是 cloud-core,最后才是 cloud-admin。
优势:开发者无需手动排序,彻底解放了构建流程的管理负担。
注意:聚合关系是单向感知的。父工程知道有哪些子模块,但子模块的
pom.xml中并不需要(也不应该)声明自己属于哪个聚合工程。子模块只需关注自身的逻辑。

随着模块数量增加,以下问题会日益凸显:
配置冗余:每个模块都要重复配置相同的编译器插件、资源过滤规则等。
版本地狱:每个模块都单独声明 Spring、MyBatis 等依赖的版本。一旦需要升级版本,必须修改几十个文件,极易遗漏导致版本冲突。
继承机制允许子模块从父模块“继承”配置,实现“一处定义,处处生效”。
继承关系的建立需要父子双方配合,但主动权在子模块。
父工程除了设置 <packaging>pom</packaging> 外,主要提供两类内容:

直接依赖 (<dependencies>):所有子模块都需要的公共库(如 lombok, slf4j)。子模块继承后自动拥有这些依赖。
依赖管理 (<dependencyManagement>):这是最核心的用法。在此处定义依赖的版本号,但不引入实际依赖。子模块如需使用,只需声明 groupId 和 artifactId,无需写版本号。
<!-- 父工程 pom.xml -->
<project>
<!-- ... 基础坐标信息 ... -->
<packaging>pom</packaging>
<!-- 1. 统一属性管理 (推荐) -->
<properties>
<java.version>17</java.version>
<spring.boot.version>3.1.0</spring.boot.version>
<mysql.version>8.0.33</mysql.version>
</properties>
<!-- 2. 公共依赖 (所有子模块自动继承) -->
<dependencies>
<dependency>
<groupId>org.projectlombok</groupId>
<artifactId>lombok</artifactId>
<scope>provided</scope>
</dependency>
</dependencies>
<!-- 3. 依赖版本锁定 (子模块按需引用,不写版本) -->
<dependencyManagement>
<dependencies>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-web</artifactId>
<version>${spring.boot.version}</version>
</dependency>
<dependency>
<groupId>com.mysql</groupId>
<artifactId>mysql-connector-j</artifactId>
<version>${mysql.version}</version>
</dependency>
</dependencies>
</dependencyManagement>
<!-- 还可以继承插件配置、仓库配置等 -->
</project>
子模块通过 <parent> 标签显式指向父工程。
<!-- 子模块 pom.xml -->
<project>
<!-- 关键点:声明父工程 -->
<parent>
<groupId>com.example.cloud</groupId>
<artifactId>cloud-parent</artifactId>
<version>1.0.0-SNAPSHOT</version>
<!-- 相对路径,默认为 ../pom.xml,若目录结构特殊需显式指定 -->
<relativePath>../pom.xml</relativePath>
</parent>
<!-- 子模块只需定义自己的 artifactId,groupId 和 version 默认继承父工程 -->
<artifactId>cloud-admin</artifactId>
<packaging>jar</packaging>
<!-- 使用依赖时,无需写版本号! -->
<dependencies>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-web</artifactId>
<!-- 版本由父工程 dependencyManagement 控制 -->
</dependency>
<dependency>
<groupId>com.mysql</groupId>
<artifactId>mysql-connector-j</artifactId>
<!-- 版本由父工程 control -->
</dependency>
</dependencies>
</project>除了 <dependencyManagement>,强烈建议使用 <properties> 来管理版本号变量。

好处:
语义化清晰:${spring.boot.version} 比硬编码 3.1.0 更易读。
覆盖灵活:子模块如果需要特殊版本,可以在自己的 <properties> 中覆盖父工程的变量值,而无需修改父工程。