做 SpringBoot 开发的同学,肯定踩过这样的坑:
引入多个依赖后,项目启动报错,日志全是「类冲突」「方法找不到」;明明导入了依赖,却提示「NoClassDefFoundError」;手动指定版本号,改来改去还是不兼容……
其实这些问题,90% 都和「依赖版本控制」有关。而 SpringBoot 早就给我们准备了最优解——BOM(Bill of Materials)。
一、为什么需要依赖管理?
我们都知道,SpringBoot 项目依赖众多,比如 Spring 核心、SpringMVC、数据库驱动、Redis 客户端、第三方工具包等。如果没有统一的版本管理,会出现两个致命问题:
1. 版本冲突
比如你手动引入 Spring 核心依赖 5.3.20,又引入 SpringBoot Web Starter 2.7.0(内置 Spring 5.3.22),两个版本的 Spring 核心类冲突,导致项目启动失败。
2. 依赖冗余、漏配
多个依赖之间有依赖关系(比如 MyBatis 依赖 Spring JDBC),手动管理时,容易漏引依赖、重复引入,或引入不兼容的版本。
3. 维护成本高
项目中几十上百个依赖,每个都手动指定版本,后期升级版本时,需要逐个修改,繁琐且容易出错。
而 SpringBoot 的依赖管理(核心是 BOM),就是帮我们解决这些问题,实现「统一版本、自动兼容、简化配置」。
二、什么是 BOM?
BOM(Bill of Materials),直译是「物料清单」,在 Maven/Gradle 中,它是一个特殊的 POM 文件,核心作用是:统一管理一组依赖的版本号。
简单来说,BOM 就像一个「版本字典」,里面定义了一系列依赖的兼容版本,你只需要引入这个 BOM,再引入相关依赖时,就不需要手动指定版本号——BOM 会自动帮你匹配最合适、最兼容的版本。
SpringBoot 中的 BOM
SpringBoot 官方提供了专属 BOM,核心是spring-boot-dependencies,它包含了 SpringBoot 生态中所有常用依赖的兼容版本(比如 Spring、SpringMVC、Redis、MySQL 驱动等)。
我们创建 SpringBoot 项目时,父工程(parent)默认引入了这个 BOM,这也是为什么我们引入 Starter 依赖时,不需要写版本号的原因!
三、SpringBoot BOM 的核心用法
SpringBoot 依赖管理的核心,就是围绕 BOM 展开,下面 3 种场景,覆盖 99% 的开发需求,复制就能用。
场景1:默认使用 SpringBoot 父工程 BOM
创建 SpringBoot 项目时,pom.xml 会默认引入父工程,而父工程已经集成了spring-boot-dependenciesBOM,我们直接引入 Starter 依赖,无需指定版本。
<!-- 父工程,集成 SpringBoot BOM --> <parent> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-parent</artifactId> <version>2.7.0</version> <!-- 只需要指定父工程版本,统一管控所有依赖版本 --> <relativePath/> </parent> <!-- 引入依赖,无需指定版本,BOM 自动匹配 --> <dependencies> <!-- Web Starter --> <dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-web</artifactId> </dependency> <!-- Redis Starter --> <dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-data-redis</artifactId> </dependency> <!-- MySQL 驱动 --> <dependency> <groupId>mysql</groupId> <artifactId>mysql-connector-java</artifactId> </dependency> </dependencies>核心优势:简单高效,无需手动管理版本,SpringBoot 帮你搞定所有依赖的兼容性。
场景2:无法继承父工程时,手动引入 BOM
有些项目(比如多模块项目的子模块、已有父工程的项目),无法继承spring-boot-starter-parent,此时可以手动引入 BOM,通过dependencyManagement标签使用。
<!-- 手动引入 SpringBoot BOM,统一管理版本 --> <dependencyManagement> <dependencies> <dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-dependencies</artifactId> <version>2.7.0</version> <type>pom</type> <scope>import</scope> <!-- 关键:导入 BOM 中的版本配置 --> </dependency> </dependencies> </dependencyManagement> <!-- 引入依赖,仍无需指定版本 --> <dependencies> <dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-web</artifactId> </dependency> </dependencies>注意:dependencyManagement只负责「版本管理」,不自动引入依赖,需要手动在dependencies中引入所需依赖。
场景3:自定义版本(覆盖 BOM 版本)
有时我们需要使用特定版本的依赖(比如项目需要 MySQL 8.0 驱动,而 BOM 默认是 5.7),此时可以手动指定版本,覆盖 BOM 中的默认版本,有两种方式:
方式1:在 dependency 中直接指定版本(局部覆盖)
<dependencies> <!-- 覆盖 BOM 中的 MySQL 驱动版本 --> <dependency> <groupId>mysql</groupId> <artifactId>mysql-connector-java</artifactId> <version>8.0.32</version> <!-- 手动指定版本,覆盖 BOM 默认值 --> </dependency> </dependencies>方式2:在 properties 中指定版本(全局覆盖)
SpringBoot BOM 中,每个依赖的版本都有对应的属性(比如 MySQL 驱动版本对应mysql.version),我们可以在 properties 中修改这些属性,全局覆盖版本。
<properties> <!-- 全局覆盖 MySQL 驱动版本 --> <mysql.version>8.0.32</mysql.version> <!-- 全局覆盖 Redis 版本 --> <redis.version>3.2.10</redis.version> </properties> <dependencies> <!-- 无需指定版本,会使用 properties 中定义的版本 --> <dependency> <groupId>mysql</groupId> <artifactId>mysql-connector-java</artifactId> </dependency> </dependencies>推荐使用方式2:全局统一管理,后期升级版本时,只需修改 properties 中的属性,无需逐个修改依赖。
四、BOM 的核心特性
•版本统一:BOM 定义了一组依赖的兼容版本,避免版本冲突;
•简化配置:引入依赖时无需手动指定版本,减少冗余配置;
•可覆盖性:允许手动指定版本,覆盖 BOM 中的默认值,灵活适配需求;
•传递性:引入 BOM 后,其管理的版本会作用于所有子依赖(比如引入 Web Starter,其依赖的 Spring 核心版本由 BOM 统一管控)。
五、依赖版本控制常见问题
依赖冲突
❌ 报错表现:ClassNotFoundException、NoSuchMethodError、jar 包重复;
✅ 解决方案:1. 优先使用 SpringBoot BOM,避免手动指定版本;2. 用 Maven 依赖树(IDEA 中 Maven → Dependencies → 查看依赖树)排查冲突依赖,排除多余依赖(用 标签)。
<!-- 排除冲突的依赖 --> <dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-web</artifactId> <exclusions> <exclusion> <groupId>org.springframework</groupId> <artifactId>spring-core</artifactId> </exclusion> </exclusions> </dependency>手动指定版本导致不兼容
❌ 错误做法:随意指定版本(比如 SpringBoot 2.7.0 搭配 Spring 6.0 版本);
✅ 正确做法:如果必须自定义版本,确保版本与 SpringBoot 版本兼容(可参考 SpringBoot 官方文档的版本兼容表)。
依赖冗余
❌ 错误做法:重复引入依赖、引入不需要的依赖;
✅ 正确做法:只引入项目必需的依赖,利用 Starter 依赖( Starter 会自动引入相关依赖,避免漏引、错引)。
总结
SpringBoot 的依赖管理,核心就是「BOM 统一管控版本」,记住这3个核心点,就能彻底摆脱依赖冲突:
1. 常规项目,直接继承 SpringBoot 父工程,享受 BOM 自动版本管理;
2. 无法继承父工程,手动引入 BOM,用 dependencyManagement 管控版本;
3. 需自定义版本,优先用 properties 全局覆盖,避免局部混乱。
依赖管理看似琐碎,但做好了能节省大量排查报错、维护版本的时间。如果你在开发中遇到过奇葩的依赖冲突,或者有更好的版本管理技巧,欢迎在评论区留言交流,一起避坑、一起进步!
别忘了点赞+在看+收藏三连,关注我,解锁更多 SpringBoot 实战干货,下期再见❤️