多模块项目的依赖之痛
一个典型的 Java 后端项目往往拆成 common、service、web、dao 等多个 Maven 模块。随着模块增多,你会遇到两个经典问题:
- 版本分裂:A 模块用 Spring 5.3.10,B 模块用 5.3.20,打包后到底哪个生效全看依赖调解规则,诡异 bug 由此而来。
- 依赖冲突:两个库分别传递依赖了不同版本的
commons-lang3,编译通过、运行报NoSuchMethodError。
本文给出一套可落地的多模块依赖管理方案。
一、用 dependencyManagement 統一版本
父 POM 里用 dependencyManagement 只声明版本、不引入依赖,子模块引用时省去 version,版本由父 POM 一锤定音。
<!-- 父 pom.xml -->
<dependencyManagement>
<dependencies>
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-core</artifactId>
<version>5.3.31</version>
</dependency>
<dependency>
<groupId>org.apache.commons</groupId>
<artifactId>commons-lang3</artifactId>
<version>3.14.0</version>
</dependency>
</dependencies>
</dependencyManagement>
<!-- 子模块:无需写 version -->
<dependencies>
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-core</artifactId>
</dependency>
</dependencies>
二、用 BOM 导入第三方版本矩阵
Spring、Jackson 这类生态会提供 BOM(Bill of Materials),一次性锁定一整套兼容版本,比手动列每个包省事得多。
<dependencyManagement>
<dependencies>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-dependencies</artifactId>
<version>2.7.18</version>
<type>pom</type>
<scope>import</scope>
</dependency>
</dependencies>
</dependencyManagement>
三、冲突排查:dependency:tree 是你的放大镜
遇到 NoClassDefFoundError / NoSuchMethodError,第一反应是跑依赖树:
mvn dependency:tree -Dincludes=org.apache.commons:commons-lang3
输出会显示哪些模块引入了哪个版本,谁把旧版本「拉」了进来。定位后,在引入方用 <exclusions> 排除,或在 dependencyManagement 强制指定高版本。
<dependency>
<groupId>com.example</groupId>
<artifactId>legacy-sdk</artifactId>
<exclusions>
<exclusion>
<groupId>org.apache.commons</groupId>
<artifactId>commons-lang3</artifactId>
</exclusion>
</exclusions>
</dependency>
四、多模块构建提速
- 并行构建:
mvn -T 1C install按 CPU 核数并行,大项目能快数倍。 - 增量构建:只构建改动模块及其依赖者,用
mvn install -pl module-a -am(also-make 连带依赖)。 - 跳过测试加速本地验证:
-DskipTests仅用于本地快速编译,CI 必须跑全量测试。
五、避免踩的坑
- 别在子模块重复声明版本:一旦写了 version 就脱离了统一管理,迟早分裂。
- 慎用 provided / system 范围:容易在不同环境里缺失,优先用标准依赖。
- 定期 mvn versions:display-dependency-updates:及时发现可升级的安全/修复版本。
小结
多模块依赖管理的核心就是「单一可信版本源」:父 POM 的 dependencyManagement + BOM 锁版本,dependency:tree 查冲突,exclusions 清杂质。做到这四点,jar 包打架的问题基本绝迹。




