微服务项目最怕的不是依赖少,而是每个模块各自声明一套版本。时间一长,provider 用一个版本的库,consumer
用另一个版本,本地能跑,部署后行为却不一样。这个项目一开始就把版本治理放进父 POM,子模块只声明“我要用什么”,不关心“它是什么版本”。
一、父工程负责两件事
<packaging>pom</packaging>
<modules>
<module>service-common</module>
<module>service-provider</module>
<module>service-consumer</module>
<module>service-gateway</module>
<module>service-mail</module>
</modules>
https://github.com/springvortex/spring-cloud-alibaba/blob/release/v1.0.0/pom.xml
packaging=pom 表示父工程不产出业务 JAR,只负责聚合和治理。执行 Maven 命令时,它会按依赖关系先构建 service-common
,再构建依赖它的业务服务。
第二件事是统一版本属性:
<properties>
<java.version>21</java.version>
<spring-boot.version>4.1.0</spring-boot.version>
<spring-cloud.version>2025.1.2</spring-cloud.version>
<spring-cloud-alibaba.version>2025.1.0.0</spring-cloud-alibaba.version>
<mybatis.plus.version>3.5.17</mybatis.plus.version>
</properties>
https://github.com/springvortex/spring-cloud-alibaba/blob/release/v1.0.0/pom.xml
版本升级时只需要改父 POM,所有子模块同步生效。
二、BOM 只管版本,不引入依赖
父 POM 通过 dependencyManagement 导入 BOM:
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-dependencies</artifactId>
<version>${spring-cloud.version}</version>
<type>pom</type>
<scope>import</scope>
</dependency>
https://github.com/springvortex/spring-cloud-alibaba/blob/release/v1.0.0/pom.xml
Spring Cloud Alibaba 也同样导入自己的 dependencies BOM。这样子模块里的依赖可以省掉版本号:
<dependency>
<groupId>com.alibaba.cloud</groupId>
<artifactId>spring-cloud-starter-alibaba-nacos-discovery</artifactId>
</dependency>
https://github.com/springvortex/spring-cloud-alibaba/blob/release/v1.0.0/service-provider/pom.xml
dependencyManagement 不会自动把依赖加进 classpath。它的意义是:当子模块真正声明这个依赖时,版本由父工程统一决定。
三、三套版本要保持兼容
Spring Boot、Spring Cloud、Spring Cloud Alibaba 不是三个独立演进的版本,它们有对应的兼容矩阵。混搭时常见问题是:启动时找不到某个自动配置类、Feign 行为异常、Gateway 配置绑定不上。
排查这类问题先看三件事:
- Boot 和 Cloud 版本是否匹配。
- Cloud 和 Alibaba 版本是否匹配。
- 子模块是否绕过父 POM 写死版本。
四、插件也统一管理
编译器、Spring Boot 打包、JaCoCo、Surefire 都放在父 POM。好处是新建业务模块时,不需要复制一整套构建配置。
<plugin>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-maven-plugin</artifactId>
</plugin>
https://github.com/springvortex/spring-cloud-alibaba/blob/release/v1.0.0/pom.xml
service-common 是普通库模块,不适合打成可执行 JAR,所以它单独设置:
<spring-boot.repackage.skip>true</spring-boot.repackage.skip>
https://github.com/springvortex/spring-cloud-alibaba/blob/release/v1.0.0/service-common/pom.xml
五、经验总结
- 父 POM 管版本和插件,子模块管业务依赖。
- BOM 解决版本一致性,不等于自动引入依赖。
- 公共库和可启动服务要区分打包方式。
- 多模块项目先构建公共模块,再构建业务模块, Maven Reactor 会自动处理这个顺序。