← 返回题目列表

Spring Boot Starter 和依赖管理的原理是什么?

高频 中等 第 12 / 25 题 更新于 2026/07/26
Spring BootStarterBOM依赖管理

简化版

Starter 是面向某项能力的依赖聚合入口,帮助一次引入一组兼容依赖;Spring Boot 的 BOM 则统一管理受支持依赖的版本。Starter 负责“需要哪些依赖”,自动配置负责“满足条件时注册哪些 Bean”,二者经常配套但职责不同。

详细版

Maven 项目可以继承 spring-boot-starter-parent,也可以在已有父工程下导入 spring-boot-dependencies BOM;Gradle 则可使用 Boot 与依赖管理能力。版本可省略仅限 BOM 已管理的依赖,业务库或未受管理组件仍要显式选择版本。

官方 Starter 通常使用 spring-boot-starter-* 命名,第三方自定义 Starter 不应占用这个官方命名空间。一个完整的自定义能力常拆成自动配置模块和 Starter 模块:前者提供条件配置,后者聚合自动配置及业务所需依赖。

完整版教学

一、Starter 解决依赖组合问题

开发 Web 应用需要 Spring MVC、JSON、校验和服务器等多个库。直接逐个选择依赖不仅繁琐,还可能组合出不兼容版本。Starter 提供一个经过验证的依赖入口:

<dependency>
    <groupId>org.springframework.boot</groupId>
    <artifactId>spring-boot-starter-web</artifactId>
</dependency>

它主要通过 Maven/Gradle 的传递依赖把常用组件带入类路径,并不意味着每个依赖都会无条件创建 Bean。

二、BOM 解决版本对齐问题

BOM 是 dependencyManagement 清单,声明一组经过兼容性测试的依赖版本。项目导入后,声明受管理依赖时通常不用重复写 version,实际依赖仍需出现在 dependencies 中;BOM 管版本,不会凭空把库加入运行时。

<dependencyManagement>
    <dependencies>
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-dependencies</artifactId>
            <version>${spring-boot.version}</version>
            <type>pom</type>
            <scope>import</scope>
        </dependency>
    </dependencies>
</dependencyManagement>

三、parent 与 BOM 的区别

spring-boot-starter-parent 继承 Boot 的依赖管理,还提供常用 Maven 插件配置、编译属性和资源过滤约定。企业项目若必须继承自己的 parent,就不能再同时继承 Boot parent,但仍可导入 spring-boot-dependencies BOM 获得版本管理。

只导入 BOM 不会自动得到 parent 的所有插件默认值,打包可执行 jar 等功能仍需配置相应 Spring Boot Maven Plugin。不能把 parent 和 BOM 看成完全等价。

四、Starter 与自动配置如何协作

Starter 把类放到 classpath,自动配置再用 @ConditionalOnClass@ConditionalOnMissingBean 等条件决定是否注册默认组件。缺少某个必需类时,对应配置不会生效;用户提供自己的 Bean 时,默认 Bean 又可能退让。

所以排查“引了 Starter 为什么没 Bean”时,要检查依赖是否真正解析成功、自动配置是否被发现、条件是否匹配,而不是认为 Starter 本身在执行初始化代码。

五、自定义 Starter 的结构

自定义 Starter 通常包含:

  1. 类型安全配置属性;
  2. 使用 @AutoConfiguration 的自动配置类;
  3. 条件注解和默认 Bean;
  4. META-INF/spring/org.springframework.boot.autoconfigure.AutoConfiguration.imports 登记;
  5. 一个聚合这些模块及必要第三方库的 Starter。

还应避免把可选依赖强制传递给所有使用者,并提供清晰的属性前缀、失败提示和覆盖点。Starter 是公共产品接口,配置兼容性与默认值同样需要版本治理。

六、版本覆盖的风险

Boot 允许覆盖受管理依赖版本,但这会跳出该版本 Boot 测试过的组合。遇到安全修复时,应优先升级到包含修复的 Boot 维护版本;确需单独覆盖,要验证二进制兼容、传递依赖和完整测试,而不是只看编译通过。

依赖冲突排查应查看 Maven dependency tree 或 Gradle dependencies,确认最终选择的版本,而不是只检查自己写在构建文件里的直接依赖。

七、用依赖解析算例看清 BOM 边界

假设项目声明 12 个依赖,其中 9 个在 Boot BOM 中受管理、3 个是公司私有库。前 9 个可以省略 version 并随 Boot 一起对齐,后 3 个仍必须由企业 BOM 或直接声明版本;导入 BOM 不会自动把这 12 个依赖加入项目。若手工把其中一个受管理库覆盖成另一大版本,构建工具可能解析成功,但运行时仍可能因方法签名不兼容出现 NoSuchMethodError。

概念主要职责会不会引入代码是否管理版本
Starter聚合典型能力所需依赖通过传递依赖引入通常借助 BOM
BOM提供受测试的版本清单不会凭空引入依赖
starter-parent继承 BOM 并提供 Maven 约定不直接替代 dependencies会,且含插件等默认
Boot Maven Plugin打包、运行等构建任务处理构建产物不负责完整依赖选择
自动配置模块条件注册 Bean是,包含配置代码版本由构建系统决定
declare starter
   → dependency graph expands
   → dependencyManagement supplies missing versions
   → conflict mediation selects final artifacts
   → classpath activates matching auto-configurations

排查版本时应查看 mvn dependency:tree 或 Gradle dependency insight 的最终结果。只看 POM 中自己写的直接依赖会漏掉传递版本、排除项和冲突仲裁,无法解释真实运行 classpath。

记忆钩子:Starter 回答“带哪些库”,BOM 回答“这些库用什么版本”,Plugin 回答“怎样构建”,自动配置回答“类路径具备后注册哪些 Bean”。

八、常见误区与追问

  • 误区:导入 BOM 就会自动引入其中所有依赖。 BOM 只提供 dependencyManagement 版本,项目仍需在 dependencies 中声明真正需要的库。
  • 误区:Starter 自己负责扫描并创建业务 Bean。 Starter 主要是依赖描述符,Bean 装配由被带入并发现的自动配置完成。
  • 误区:覆盖一个受管理依赖版本只要编译通过就安全。 这会跳出 Boot 测试组合,还需验证二进制兼容、传递依赖和运行测试。
  • 追问:企业项目已有 parent 怎么使用 Boot 依赖管理? 可导入 spring-boot-dependencies BOM,但不会自动获得 starter-parent 的全部 Maven 插件和资源处理约定。
  • 追问:第三方 Starter 为什么不应叫 spring-boot-starter-xxx? 该命名空间保留给官方 Starter,第三方通常使用“项目名-spring-boot-starter”避免误导。
  • 追问:引入 Starter 后为什么仍没有目标 Bean? 依赖可能被排除、自动配置未登记、条件不满足或用户 Bean 触发退让,应结合依赖树和条件报告排查。

九、加强记忆

Starter 管依赖组合,BOM 管兼容版本,自动配置管 Bean 装配。继承 Boot parent 会额外获得 Maven 构建约定,只导入 BOM 主要获得版本管理;自定义 Starter 也应把依赖入口与条件自动配置分清。