spring boot 依赖版本无需手动写死,依靠 io.spring.dependency-management 插件与 bom(bill of materials)自动对齐;该插件确保子模块正确继承 spring-boot-dependencies 中定义的兼容版本,避免因版本缺失或错配导致编译失败(如 could not resolve)或运行时异常(如 noclassdeffounderror)。

Spring Boot 依赖版本不用手动写死,靠 io.spring.dependency-management 插件 + BOM(Bill of Materials)自动对齐。只要插件配置正确、BOM 导入到位,spring-boot-starter-web 这类依赖连版本号都不用写。
为什么不能只用 org.springframework.boot 插件?
Spring Boot Gradle 插件(如 org.springframework.boot:3.3.5)默认会自动应用 io.spring.dependency-management,但前提是它被正确加载且作用域覆盖到所有子模块。如果只在根项目声明插件却不显式 apply 到子项目,或者用了 apply false 却忘了在 subprojects 中补上,就会出现:子模块里写 implementation 'org.springframework.boot:spring-boot-starter-data-jpa' 时编译报错 —— Gradle 找不到默认版本。
常见错误现象:
-
Could not resolve org.springframework.boot:spring-boot-starter-web:(末尾缺版本号,又没 BOM 支撑) - 子模块能编译,但运行时报
java.lang.NoClassDefFoundError: org/springframework/boot/autoconfigure/web/servlet/WebMvcAutoConfiguration(实际是版本错配导致类加载不全)
根本原因:BOM 没导入,或只导入了一半。
实操建议:
- 根项目的
plugins块中声明id 'io.spring.dependency-management' version '1.1.7' apply false(注意apply false) - 在
subprojects块中显式apply plugin: 'io.spring.dependency-management' - 确保
dependencyManagement块里调用了mavenBom org.springframework.boot.gradle.plugin.SpringBootPlugin.BOM_COORDINATES—— 这个常量会动态匹配你当前使用的 Spring Boot 版本,别手写字符串
dependencies 里到底要不要写版本号?
绝大多数 Spring Boot 官方 starter(如 spring-boot-starter-web、spring-boot-starter-validation)和它直接管理的第三方库(如 tomcat-embed-core、jackson-databind),**必须不写版本号**。写了反而可能绕过 BOM 控制,引发隐性冲突。
但以下情况必须写版本:
- 非 Spring Boot BOM 管理的库,比如
com.baomidou:mybatis-plus-boot-starter—— 它不在官方清单里,得自己在dependencyManagement.dependencies中统一声明版本 - 你想强制降级某个传递依赖(例如 Spring Boot 默认带
net.minidev:json-smart:2.4.11,但某 SDK 要求2.4.7),就得在dependencies块里显式写implementation 'net.minidev:json-smart:2.4.7' - 使用了新版 Spring Boot(如 3.3.x),但某个生态组件还没适配(如旧版
springfox-swagger2),只能手动指定兼容版本并排除冲突传递依赖
关键判断点:查 Spring Boot 3.3.5 的 dependency versions 表,里面列出的坐标,就别写版本。
多模块项目里,公共依赖该放哪统一管?
不是所有依赖都适合塞进根项目的 dependencyManagement。比如 lombok、slf4j-api、assertj 这类通用工具库,应该用 platform 或 java-platform 插件建独立 BOM 模块,再让各子模块 implementation platform(...) 引入。
原因很实际:
-
dependencyManagement只影响当前构建脚本里的dependencies块,对其他模块的constraints不生效 - 把非 Spring 生态的库硬塞进 Spring Boot BOM,容易混淆语义,后续升级 Spring Boot 时还得手动清理
- 不同团队维护不同模块时,平台级依赖(如日志、测试、代码生成)和框架级依赖(如 Web、Data、Cloud)理应分层管控
简单做法:
- 新建
gradle/libs.versions.toml(Gradle 8.0+ 推荐),用[versions]和[libraries]分离定义,再通过alias统一引用 - 若还在用 Groovy,可在根项目
build.gradle里定义ext.lombokVersion = '1.18.30',子模块用"org.projectlombok:lombok:${rootProject.ext.lombokVersion}"
最易被忽略的一点:BOM 的导入顺序有影响。如果同时引入多个 BOM(比如 Spring Boot BOM + JUnit BOM + 自定义 BOM),后导入的会覆盖前面同名依赖的版本约束。调试时别只盯着自己写的那行 mavenBom,要 ./gradlew dependencies --configuration compileClasspath 看实际解析树。











