Maven 多模块项目管理
2025/11/30大约 7 分钟
Maven 多模块项目管理笔记
📚 基本概念
什么是 Maven 多模块项目?
Maven 多模块项目由一个父工程和多个子模块组成:
- 父工程:统一管理依赖版本、引入公共依赖、配置构建插件
- 子模块:继承父工程配置,引入特定依赖,实现具体业务
优势
- ✅ 统一管理依赖版本,避免版本冲突
- ✅ 公共依赖只需在父工程引入一次,所有子模块自动继承
- ✅ 代码复用,模块间可以相互依赖
- ✅ 统一构建,一次性编译所有模块
- ✅ 项目结构清晰,便于维护
🏗️ 项目结构
MyProject/ (父工程)
├── pom.xml (父工程 POM - 管理版本 + 公共依赖)
├── common/ (公共模块)
│ ├── pom.xml
│ └── src/
├── server/ (服务端模块)
│ ├── pom.xml
│ └── src/
└── web/ (前端模块)
├── pom.xml
└── src/📝 父工程配置详解
1. 基础配置
<?xml version="1.0" encoding="UTF-8"?>
<project>
<modelVersion>4.0.0</modelVersion>
<!-- 继承 Spring Boot Parent -->
<parent>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-parent</artifactId>
<version>3.0.2</version>
<relativePath/>
</parent>
<groupId>com.mycompany</groupId>
<artifactId>MyProject</artifactId>
<version>1.0.0</version>
<packaging>pom</packaging> <!-- 必须是 pom -->
<!-- 声明子模块 -->
<modules>
<module>common</module>
<module>server</module>
<module>web</module>
</modules>
</project>2. 版本属性管理
<properties>
<java.version>17</java.version>
<project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
<!-- 统一管理第三方依赖版本 -->
<lombok.version>1.18.36</lombok.version>
<mybatis-plus.version>3.5.5</mybatis-plus.version>
<druid.version>1.2.19</druid.version>
<knife4j.version>4.0.0</knife4j.version>
</properties>3. 依赖版本管理(只声明不引入)
<dependencyManagement>
<dependencies>
<!-- MyBatis Plus -->
<dependency>
<groupId>com.baomidou</groupId>
<artifactId>mybatis-plus-boot-starter</artifactId>
<version>${mybatis-plus.version}</version>
</dependency>
<!-- Druid 连接池 -->
<dependency>
<groupId>com.alibaba</groupId>
<artifactId>druid-spring-boot-starter</artifactId>
<version>${druid.version}</version>
</dependency>
<!-- Knife4j 接口文档 -->
<dependency>
<groupId>com.github.xiaoymin</groupId>
<artifactId>knife4j-openapi3-spring-boot-starter</artifactId>
<version>${knife4j.version}</version>
</dependency>
</dependencies>
</dependencyManagement>📌 重点: <dependencyManagement> 只是声明版本号,子模块需要显式引入才会生效!
4. 公共依赖(所有子模块自动继承)
<dependencies>
<!-- Lombok - 所有模块都需要 -->
<dependency>
<groupId>org.projectlombok</groupId>
<artifactId>lombok</artifactId>
</dependency>
<!-- Spring Boot Test - 所有模块都需要测试 -->
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-test</artifactId>
<scope>test</scope>
</dependency>
<!-- 工具类 - 所有模块都可能用到 -->
<dependency>
<groupId>cn.hutool</groupId>
<artifactId>hutool-all</artifactId>
<version>5.8.23</version>
</dependency>
</dependencies>📌 重点: 这里引入的依赖会被所有子模块自动继承,无需在子模块中再次声明!
5. 完整的父工程示例
<?xml version="1.0" encoding="UTF-8"?>
<project>
<modelVersion>4.0.0</modelVersion>
<parent>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-parent</artifactId>
<version>3.0.2</version>
</parent>
<groupId>com.mycompany</groupId>
<artifactId>MyProject</artifactId>
<version>1.0.0</version>
<packaging>pom</packaging>
<modules>
<module>common</module>
<module>server</module>
</modules>
<properties>
<java.version>17</java.version>
<mybatis-plus.version>3.5.5</mybatis-plus.version>
</properties>
<!-- 版本管理:只声明版本 -->
<dependencyManagement>
<dependencies>
<dependency>
<groupId>com.baomidou</groupId>
<artifactId>mybatis-plus-boot-starter</artifactId>
<version>${mybatis-plus.version}</version>
</dependency>
</dependencies>
</dependencyManagement>
<!-- 公共依赖:所有子模块自动继承 -->
<dependencies>
<dependency>
<groupId>org.projectlombok</groupId>
<artifactId>lombok</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-test</artifactId>
<scope>test</scope>
</dependency>
</dependencies>
</project>📦 子模块配置详解
1. 基础配置
<?xml version="1.0" encoding="UTF-8"?>
<project>
<modelVersion>4.0.0</modelVersion>
<!-- 继承父工程 -->
<parent>
<groupId>com.mycompany</groupId>
<artifactId>MyProject</artifactId>
<version>1.0.0</version>
</parent>
<artifactId>server</artifactId>
<name>server</name>
<description>服务端模块</description>
</project>2. 引入依赖
<dependencies>
<!-- 从 dependencyManagement 继承版本(不需要写版本号) -->
<dependency>
<groupId>com.baomidou</groupId>
<artifactId>mybatis-plus-boot-starter</artifactId>
</dependency>
<!-- Spring Boot Web -->
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-web</artifactId>
</dependency>
<!-- 依赖其他子模块 -->
<dependency>
<groupId>com.mycompany</groupId>
<artifactId>common</artifactId>
<version>${project.version}</version>
</dependency>
<!-- 注意:父工程 <dependencies> 中的依赖已自动继承,无需再写! -->
<!-- 例如:lombok、spring-boot-starter-test 已经有了 -->
</dependencies>3. 完整的子模块示例
<?xml version="1.0" encoding="UTF-8"?>
<project>
<modelVersion>4.0.0</modelVersion>
<parent>
<groupId>com.mycompany</groupId>
<artifactId>MyProject</artifactId>
<version>1.0.0</version>
</parent>
<artifactId>server</artifactId>
<dependencies>
<!-- Web 支持 -->
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-web</artifactId>
</dependency>
<!-- 数据库相关 -->
<dependency>
<groupId>com.baomidou</groupId>
<artifactId>mybatis-plus-boot-starter</artifactId>
</dependency>
<!-- 依赖 common 模块 -->
<dependency>
<groupId>com.mycompany</groupId>
<artifactId>common</artifactId>
<version>${project.version}</version>
</dependency>
</dependencies>
<!-- 启动类所在模块需要配置打包插件 -->
<build>
<plugins>
<plugin>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-maven-plugin</artifactId>
</plugin>
</plugins>
</build>
</project>🎯 依赖管理的两种方式对比
方式1:<dependencyManagement> - 版本管理
<!-- 父工程 -->
<dependencyManagement>
<dependencies>
<dependency>
<groupId>com.baomidou</groupId>
<artifactId>mybatis-plus-boot-starter</artifactId>
<version>3.5.5</version>
</dependency>
</dependencies>
</dependencyManagement>
<!-- 子模块 -->
<dependencies>
<!-- 需要显式引入,但不需要写版本号 -->
<dependency>
<groupId>com.baomidou</groupId>
<artifactId>mybatis-plus-boot-starter</artifactId>
</dependency>
</dependencies>特点:
- ✅ 只声明版本,不引入依赖
- ✅ 子模块需要时才显式引入
- ✅ 适合:不是所有模块都需要的依赖
方式2:<dependencies> - 公共依赖
<!-- 父工程 -->
<dependencies>
<dependency>
<groupId>org.projectlombok</groupId>
<artifactId>lombok</artifactId>
</dependency>
</dependencies>
<!-- 子模块 -->
<!-- 自动继承,无需再写任何代码 -->特点:
- ✅ 直接引入依赖
- ✅ 所有子模块自动继承
- ✅ 适合:所有模块都需要的依赖(Lombok、测试框架、工具类等)
📋 依赖分类建议
父工程 <dependencies> - 公共依赖(所有模块都要)
<dependencies>
<!-- 代码简化 -->
<dependency>
<groupId>org.projectlombok</groupId>
<artifactId>lombok</artifactId>
</dependency>
<!-- 测试框架 -->
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-test</artifactId>
<scope>test</scope>
</dependency>
<!-- 工具类库 -->
<dependency>
<groupId>cn.hutool</groupId>
<artifactId>hutool-all</artifactId>
<version>5.8.23</version>
</dependency>
<!-- JSON 处理 -->
<dependency>
<groupId>com.fasterxml.jackson.core</groupId>
<artifactId>jackson-databind</artifactId>
</dependency>
</dependencies>父工程 <dependencyManagement> - 版本管理(按需引入)
<dependencyManagement>
<dependencies>
<!-- 数据库相关(只有 server 模块需要) -->
<dependency>
<groupId>com.baomidou</groupId>
<artifactId>mybatis-plus-boot-starter</artifactId>
<version>3.5.5</version>
</dependency>
<dependency>
<groupId>com.alibaba</groupId>
<artifactId>druid-spring-boot-starter</artifactId>
<version>1.2.19</version>
</dependency>
<!-- 接口文档(只有 web 模块需要) -->
<dependency>
<groupId>com.github.xiaoymin</groupId>
<artifactId>knife4j-openapi3-spring-boot-starter</artifactId>
<version>4.0.0</version>
</dependency>
<!-- Redis(只有需要缓存的模块) -->
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-data-redis</artifactId>
</dependency>
</dependencies>
</dependencyManagement>🔧 常用命令
构建相关
# 清理并安装整个项目(在父工程目录)
mvn clean install
# 跳过测试
mvn clean install -DskipTests
# 只构建某个模块
cd server
mvn clean package
# 构建指定模块及其依赖
mvn clean install -pl server -am查看依赖
# 查看依赖树
mvn dependency:tree
# 查看某个模块的依赖树
mvn dependency:tree -pl server
# 分析依赖冲突
mvn dependency:analyze💡 最佳实践
1. 模块划分原则
common (公共模块)
├── entity (实体类)
├── enums (枚举)
├── constant (常量)
├── utils (工具类)
└── exception (自定义异常)
server (服务端模块)
├── service (业务逻辑)
├── mapper (数据访问)
└── config (配置类)
web (Web 层)
├── controller (控制器)
├── interceptor (拦截器)
└── filter (过滤器)2. 公共依赖选择原则
应该放在父工程 <dependencies> 的:
- ✅ Lombok(所有模块都用来简化代码)
- ✅ Spring Boot Test(所有模块都需要测试)
- ✅ 工具类库(Hutool、Guava 等)
- ✅ JSON 处理(Jackson、Fastjson)
- ✅ 日志框架(Logback、Log4j2)
应该放在 <dependencyManagement> 的:
- ✅ 数据库相关(只有 server 需要)
- ✅ Redis(只有需要缓存的模块)
- ✅ MQ(只有需要消息队列的模块)
- ✅ 接口文档(只有 web 需要)
- ✅ 安全框架(只有 web 需要)
3. 版本管理规范
<properties>
<!-- 项目版本 -->
<revision>1.0.0</revision>
<!-- JDK 版本 -->
<java.version>17</java.version>
<maven.compiler.source>17</maven.compiler.source>
<maven.compiler.target>17</maven.compiler.target>
<!-- 编码 -->
<project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
<!-- 第三方依赖版本 -->
<mybatis-plus.version>3.5.5</mybatis-plus.version>
<druid.version>1.2.19</druid.version>
</properties>⚠️ 常见问题
1. 依赖重复引入
问题: 父工程 <dependencies> 已引入,子模块又引入一次
<!-- ❌ 错误:重复引入 -->
<!-- 父工程已经在 <dependencies> 引入了 lombok -->
<dependencies>
<dependency>
<groupId>org.projectlombok</groupId>
<artifactId>lombok</artifactId> <!-- 不需要再写 -->
</dependency>
</dependencies>解决: 检查父工程 <dependencies>,如果已引入就不用再写
2. 版本冲突
问题: 多个模块引入同一依赖的不同版本
解决: 在父工程 <dependencyManagement> 统一版本
<dependencyManagement>
<dependencies>
<dependency>
<groupId>com.alibaba</groupId>
<artifactId>fastjson</artifactId>
<version>2.0.43</version>
</dependency>
</dependencies>
</dependencyManagement>3. 子模块找不到
问题: Maven 提示找不到子模块
检查:
<modules>中的名称与文件夹名一致- 子模块的 pom.xml 存在且格式正确
<!-- 父工程 -->
<modules>
<module>server</module> <!-- 必须与文件夹名一致 -->
</modules>4. 依赖不生效
问题: 在 <dependencyManagement> 中声明了但子模块用不了
原因: <dependencyManagement> 只管理版本,不引入依赖
解决: 子模块需要显式引入
<!-- 子模块 -->
<dependencies>
<dependency>
<groupId>com.baomidou</groupId>
<artifactId>mybatis-plus-boot-starter</artifactId>
<!-- 版本号从父工程继承 -->
</dependency>
</dependencies>📊 配置对比表
| 配置项 | <dependencyManagement> | <dependencies> |
|---|---|---|
| 作用 | 只声明版本,不引入依赖 | 直接引入依赖 |
| 子模块 | 需要显式引入才生效 | 自动继承,无需声明 |
| 版本号 | 必须指定 | 可继承或指定 |
| 适用场景 | 不是所有模块都需要的依赖 | 所有模块都需要的依赖 |
| 典型示例 | 数据库、Redis、MQ | Lombok、测试框架、工具类 |
🎯 总结口诀
父工程两大法宝:
1. <dependencyManagement> - 只管版本不引入,子模块按需选
2. <dependencies> - 公共依赖全引入,子模块自动继承
子模块简单明了:
1. 显式引入需要的依赖(版本从父工程继承)
2. 公共依赖无需再写(自动继承父工程的)
3. 依赖其他模块要写完整坐标记住核心原则:
- 📌 父工程管版本 + 公共依赖
- 📌 子模块选择性引入特定依赖
- 📌 避免重复,版本统一,结构清晰
