依赖管理
依赖管理机制概述
从 Spring 转到 Spring Boot 的最重大的改变应该就是,以前整合 Spring + MyBatis + SpringMVC 我们需要写一大堆的配置文件,堪称配置文件地狱,我们还要在 pom.xml 文件里引入各种类型的 jar 包,Mybatis 的、SpringMVC 的、Spring-aop 的,Spring-context 等等。
使用 SpringBoot
后,新建一个项目几乎不需要做任何改动,我们就可以运行起来。pom
文件里,我们只需要引入一个spring-boot-starter-web
就可以,之前我们所做的一切,SpringBoot
都在底层帮我们做了。
Spring Boot 的依赖管理机制主要通过以下几个核心组件实现:
- Parent POM(父 POM):提供依赖版本管理
- Starter Dependencies(启动器依赖):预配置的依赖集合
- Auto-Configuration(自动配置):基于类路径自动配置 Bean
- Dependency Management Plugin:Gradle/Maven 插件支持
理解约定优于配置
约定优于配置(Convention over Configuration / CoC),又称约定编程,是一种软件设计规范,本质上是对系统,类库或框架中一些东西。
总体来说,核心内容就是我们需要一个大众化合理的默认值(缺省值)
简单来说就是假如你所期待的配置 与 约定的配置 一致,那么就可以不做任何配置,约定不符合期待时,才需要对约定进行替换配置。约定其实就是一个规范,遵循了规范,那么就存在通用性。存在了通用性,那么事情就会变得相对简单 ,程序员之间的沟通成本就会降低,工作效率会提升,合作也会变得更加简单。
例如在模型中存在一个名为User的类,那么对应到数据库会存在一个名为 user 的表,只有偏离这个约定时才需要做相关的配置(例如你想将表名命名为:t_user等非user时才需要写关于这个名字的配置)
父项目所做的依赖管理
开发什么场景,导入什么场景启动器,maven 会根据依赖传递原则,自动把这个场景的所有核心依赖全部导入进来
spring-boot-starter-parent
如何进行依赖指定
每个 Spring Boot 项目,pom.xml文件都会给我们定义一个 parent 节点,它管理了大量常用依赖的版本。
1 | <parent> |
该节点指定了version
版本号,所以在 pom.xml
文件里我们很多引入的依赖都没有定义版本号,但这样也不会出错,因为SpringBoot
帮我们为一些常用的依赖默认指定了版本号。
作用机制:
- 预定义了数百个依赖的版本号
- 提供了合理的资源过滤配置
- 设置了插件配置
- 提供了依赖管理(dependency management)
进入spring-boot-starter-parent
这个jar包,会发现它的父项目是spring-boot-dependencies
Spring Boot 使用一个中央的 Maven pom 文件,通常称为 “Spring Boot Dependencies POM”。这个 pom 文件定义了所有支持的库的版本,它充当所有 Spring Boot 应用的父 pom 或者在 Gradle 项目中通过插件方式引用。这样做的好处是:
- 统一版本控制:通过在这个中心 POM 中定义库版本,所有引入的库将默认使用这些版本,保证了依赖的一致性和兼容性。
- 简化依赖声明:开发者在自己的项目 POM 中引入依赖时,可以不必指定版本号。Maven 会自动根据父 POM 文件解析正确的版本。
自动版本仲裁与依赖版本覆盖
spring-boot-dependencies
还会进行自动版本仲裁,即如果程序员没有指定某个
依赖的 jar
的版本,则以父项目指定的版本为准。
1 | <parent> |
而在这个依赖里,就声明了很多开发中常用依赖的版本号
所以在你 pom.xml 文件中引入 jar
的时候,如果该依赖在spring-boot-dependencies
中定义了版本号,那么你可以不写。如果你想使用其他的版本号,那么也可以在
pom.xml 中导入依赖时候定义 version
,遵循就近原则。
覆盖依赖版本
1 | <dependency> |
使用 properties 指定版本号
在某些情况下,为了方便管理多个依赖项的版本,你也可以在项目的 properties 部分中定义版本号,然后在依赖中引用这些属性:
1 | <!-- 使用 properties 中定义的版本 --> |
这种写法就是将依赖jar
包的配置信息,和配置版本分开来编写
- 在
<properties>
标签中,配置 jar 的版本信息 ,可以配置多个不同的 jar 包的版本信息 - 在
<dependencies>
标签中,配置 jar 的 配置坐标信息 ,可以配置多个 jar

依赖冲突的解决
当不同的依赖项或 starters 引入了同一个库的不同版本时,Spring Boot 依赖管理机制和构建工具的版本冲突解决策略会起作用:
- Maven:默认使用 “最近优先” 策略,即项目依赖树中距离根最近的版本将被使用。
- Gradle:默认也是使用 “最近优先” 策略,但提供了更多配置选项来调整这一行为,例如强制使用某些版本。
starter场景启动器
Starter 是 Spring Boot 的核心概念,它将相关的依赖打包在一起,遵循”约定优于配置”的原则。
一句话,开发什么场景,导入什么场景启动器,maven 会根据依赖传递原则,自动把这个场景的所有核心依赖全部导入进来
命名规范:
- 官方 Starter:
spring-boot-starter-*
- 第三方 Starter:
*-spring-boot-starter
Spring Boot Starters 是预设的依赖描述符,当你在项目中引入任何一个 starter 时,实际上是在引入一组库和模块,这些都是为了支持特定的功能集(如 Web 开发、数据库访问等)。Starters 依赖于 Spring Boot 的依赖管理系统来确保所有引入的库都是兼容的版本。
例如,我们之前学习到的 web 开发引入了,该 starter 将导入与 web 开发相关的所有包。
当你使用 Spring Initializr 或其他工具创建一个 Spring Boot
项目时,生成的 pom.xml
文件通常会包含 Spring Boot 的父 POM
和至少一个 starter。
1 |
|
spring-boot-starter-parent
是作为父 POM
使用的,它已经定义了许多库的兼容版本,而我们添加的
spring-boot-starter-web
包含了开发 web
应用所需的所有依赖,如 Tomcat 和 Spring MVC。
所以在 Spring Boot
项目中,我们只需要引入spring-boot-starter-web
包就可以写接口并且进行访问,因为在这个
starter 中整合了我们之前写 Spring
项目时引入的spring-aop
、spring-context
、spring-webmvc
等
jar 包,包括 tomcat,所以SpringBoot 项目不需要外部的 tomcat,只需要启动
application 类使用内置的 tomcat 服务器即可。
依赖树

例如我们常用的 Web 应用 Starter 包含的依赖如下:
- spring-boot-starter(核心启动器)
- spring-boot-starter-tomcat(嵌入式 Tomcat)
- spring-webmvc(Spring MVC)
- spring-web(Spring Web)
- jackson(JSON 处理)
数据库 starter :
1 | <dependency> |
包含的依赖:
- spring-boot-starter-jdbc
- hibernate-core
- spring-data-jpa
- spring-aspects
测试 starter :
1 | <dependency> |
包含的依赖
- JUnit 5
- Mockito
- AssertJ
- Hamcrest
- Spring Test
所有场景启动器最底层的依赖就是spring-boot-starter
,该
jar 包是核心启动包,这个依赖也是 SpringBoot
自动配置的核心依赖,包含了自动配置的支持,日志以及YAML。Core starter, including auto-configuration support, logging and YAML
,这是官方对它的描述。
而这个spring-boot-autoconfigure
就关系到我们接下来要说的SpringBoot自动配置功能。
依赖传递
- Maven:当一个依赖项被引入到项目中时,这个依赖的所有传递依赖也会被自动引入。Maven 会根据依赖树来解析哪些依赖是必要的,同时检查和解决版本冲突。
- Gradle:Gradle 也处理传递依赖,并且提供了灵活的依赖解析策略,使得开发者可以更细致地控制版本和依赖。