【Maven】多module项目优雅的实现pom依赖管理
【Maven】多module项目优雅的实现pom依赖管理
- 【一】方案设计原则
- 【二】项目结构示例
- 【三】实现思路
- 【1】可能的问题点:
- 【2】解决方案的思路:
- 【3】需要注意的地方:
- 【4】可能的错误:
- 【四】实现案例
- 【1】父POM设计(parent-project/pom.xml)
- 【2】子模块示例(common-core/pom.xml)
- 【3】模块间依赖(service-module/pom.xml)
- 【五】总结
【一】方案设计原则
(1)统一依赖版本管理
所有依赖版本在父POM中集中定义,子模块无需指定版本号。
(2)模块职责分离
按功能划分模块(如核心工具、数据访问、API接口等),减少耦合。
(3)依赖继承与复用
公共依赖由父模块管理,模块间通过引入所需依赖。
(4)BOM集成
使用Spring Boot和第三方库的BOM(Bill of Materials)统一管理版本。
(5)插件集中配置
在父POM中统一配置编译、打包等插件,确保构建一致性。
【二】项目结构示例
parent-project(根项目)
├── pom.xml # 父POM
├── common-core # 通用工具模块
│ └── pom.xml
├── common-dao # 数据访问模块
│ └── pom.xml
├── api-module # API接口模块
│ └── pom.xml
└── service-module # 业务逻辑模块
└── pom.xml
【三】实现思路
通常,一个多模块项目有一个父pom,然后各个子模块继承这个父pom。父pom负责管理公共的依赖版本、插件配置等。子模块可以声明自己的依赖,而版本号由父pom统一管理。这样可以避免版本冲突,也方便统一升级。
优雅管理可能包括:依赖版本统一管理、依赖分类(比如核心依赖、工具类依赖)、避免重复声明、处理模块之间的依赖关系等。
【1】可能的问题点:
(1)父pom如何管理所有依赖的版本?
(2)如何将依赖按功能分组,比如分成dependencies和dependencyManagement?
(3)如何处理不同模块间的依赖共享?
(4)如何避免子模块中重复声明版本号?
(5)如何管理插件的版本和配置?
【2】解决方案的思路:
(1)使用父pom的dependencyManagement来统一管理所有依赖的版本,子模块引入依赖时不需要指定版本。
(2)将常用依赖组合成bom(Bill of Materials),或者使用Spring Boot已有的BOM,比如spring-boot-dependencies。
(3)将项目分为多个模块,比如核心模块、通用工具模块、API模块、服务模块等,每个模块负责特定的功能,减少重复依赖。
(4)在父pom中定义公共的插件管理,确保所有子模块使用相同的插件版本和配置。
(5)使用模块化的依赖管理,比如将数据库相关依赖、Web相关依赖分别管理,方便按需引入。
【3】需要注意的地方:
(1)父pom中的依赖管理部分应该清晰,按功能或类别分组,方便查找和维护。
(2)子模块只声明需要的依赖,不重复版本。
(3)避免循环依赖,尤其是在模块之间的依赖关系上。
(4)使用import来引入其他BOM,特别是当项目需要整合多个BOM时,比如同时使用Spring Boot和Spring Cloud的BOM。
【4】可能的错误:
(1)在子模块中错误地指定了版本号,导致父pom的版本管理失效。
(2)模块之间的依赖关系没有正确声明,导致编译或运行时缺少必要的依赖。
(3)没有正确管理插件的版本,导致构建不一致。
(4)父pom中漏掉了某些公共依赖的管理,导致子模块需要自行管理版本,引发冲突。
【四】实现案例
【1】父POM设计(parent-project/pom.xml)
<?xml version="1.0" encoding="UTF-8"?>
<project>
<modelVersion>4.0.0</modelVersion>
<groupId>com.example</groupId>
<artifactId>parent-project</artifactId>
<version>1.0.0-SNAPSHOT</version>
<packaging>pom</packaging>
<!-- 模块声明 -->
<modules>
<module>common-core</module>
<module>common-dao</module>
<module>api-module</module>
<module>service-module</module>
</modules>
<!-- 继承Spring Boot父POM -->
<parent>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-parent</artifactId>
<version>3.1.5</version>
<relativePath/> <!-- 从仓库查找 -->
</parent>
<!-- 依赖管理:统一版本 -->
<dependencyManagement>
<dependencies>
<!-- 集成Spring Cloud BOM(可选) -->
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-dependencies</artifactId>
<version>2022.0.4</version>
<type>pom</type>
<scope>import</scope>
</dependency>
<!-- 自定义依赖版本 -->
<dependency>
<groupId>com.google.guava</groupId>
<artifactId>guava</artifactId>
<version>32.1.2-jre</version>
</dependency>
<dependency>
<groupId>org.projectlombok</groupId>
<artifactId>lombok</artifactId>
<version>1.18.28</version>
<scope>provided</scope>
</dependency>
</dependencies>
</dependencyManagement>
<!-- 公共依赖(所有子模块继承) -->
<dependencies>
<!-- Spring Boot Starter -->
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter</artifactId>
</dependency>
<!-- Lombok -->
<dependency>
<groupId>org.projectlombok</groupId>
<artifactId>lombok</artifactId>
<scope>provided</scope>
</dependency>
</dependencies>
<!-- 插件管理 -->
<build>
<pluginManagement>
<plugins>
<plugin>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-maven-plugin</artifactId>
</plugin>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-compiler-plugin</artifactId>
<configuration>
<source>17</source>
<target>17</target>
</configuration>
</plugin>
</plugins>
</pluginManagement>
</build>
</project>
【2】子模块示例(common-core/pom.xml)
<?xml version="1.0" encoding="UTF-8"?>
<project>
<modelVersion>4.0.0</modelVersion>
<parent>
<groupId>com.example</groupId>
<artifactId>parent-project</artifactId>
<version>1.0.0-SNAPSHOT</version>
</parent>
<artifactId>common-core</artifactId>
<!-- 声明模块特有依赖 -->
<dependencies>
<dependency>
<groupId>com.google.guava</groupId>
<artifactId>guava</artifactId> <!-- 版本由父POM管理 -->
</dependency>
</dependencies>
</project>
【3】模块间依赖(service-module/pom.xml)
<?xml version="1.0" encoding="UTF-8"?>
<project>
<modelVersion>4.0.0</modelVersion>
<parent>
<groupId>com.example</groupId>
<artifactId>parent-project</artifactId>
<version>1.0.0-SNAPSHOT</version>
</parent>
<artifactId>service-module</artifactId>
<dependencies>
<!-- 依赖其他模块 -->
<dependency>
<groupId>com.example</groupId>
<artifactId>common-core</artifactId>
<version>${project.version}</version>
</dependency>
<dependency>
<groupId>com.example</groupId>
<artifactId>common-dao</artifactId>
<version>${project.version}</version>
</dependency>
<!-- Spring Boot Web -->
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-web</artifactId>
</dependency>
</dependencies>
</project>
【五】总结
(1)分层管理依赖
父POM:管理全局依赖版本、插件和公共配置。
子模块:仅声明自身需要的依赖,不重复定义版本。
(2)活用BOM
通过导入Spring Boot、Spring Cloud或其他第三方BOM,简化版本协调。
(3)模块化设计
每个模块职责单一,通过依赖传递共享通用组件。
(4)版本变量提取
对频繁变更的版本号,可在父POM中定义集中管理。
(5)持续梳理依赖
定期使用mvn dependency:tree分析依赖树,避免冗余和冲突。