Spring Boot的起步依赖原理
·
Spring Boot的起步依赖原理
一句话理解起步依赖
起步依赖是"一键式套餐":
- 传统Spring:点菜 → 要自己搭配(A菜+B菜+C调料)
- Spring Boot:点套餐 → 直接给你配好(XX套餐 = 主食+配菜+饮料)
比如:spring-boot-starter-web= Tomcat + Spring MVC + Jackson + …
从传统Spring到Spring Boot的进化
传统Spring项目(Maven配置)
<!-- 要开发Web应用,需要手动配一堆依赖 -->
<dependencies>
<!-- Spring Core -->
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-core</artifactId>
<version>5.3.23</version>
</dependency>
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-web</artifactId>
<version>5.3.23</version>
</dependency>
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-webmvc</artifactId>
<version>5.3.23</version>
</dependency>
<!-- Jackson for JSON -->
<dependency>
<groupId>com.fasterxml.jackson.core</groupId>
<artifactId>jackson-databind</artifactId>
<version>2.13.4</version>
</dependency>
<!-- Servlet API -->
<dependency>
<groupId>javax.servlet</groupId>
<artifactId>javax.servlet-api</artifactId>
<version>4.0.1</version>
<scope>provided</scope>
</dependency>
<!-- Tomcat -->
<dependency>
<groupId>org.apache.tomcat.embed</groupId>
<artifactId>tomcat-embed-core</artifactId>
<version>9.0.68</version>
</dependency>
<!-- 还要配几十行... -->
</dependencies>
Spring Boot项目(一键搞定)
<!-- 只需要一个起步依赖 -->
<dependencies>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-web</artifactId>
</dependency>
</dependencies>
对比:
- 行数:50+行 → 5行
- 版本管理:手动指定 → 自动管理
- 依赖冲突:经常发生 → 自动解决
起步依赖的目录结构
spring-boot-starter-parent
├── spring-boot-dependencies # 版本管理
├── spring-boot-starter # 核心启动器
├── spring-boot-starter-web # Web启动器
├── spring-boot-starter-data-jpa # JPA启动器
├── spring-boot-starter-security # 安全启动器
├── spring-boot-starter-test # 测试启动器
└── ... 50+个官方starter
起步依赖的实现原理
1. 父POM统一版本管理
spring-boot-dependencies.pom:
<!-- 在Spring Boot父POM中定义了所有依赖的版本 -->
<properties>
<activemq.version>5.16.5</activemq.version>
<antlr2.version>2.7.7</antlr2.version>
<appengine-sdk.version>1.9.98</appengine-sdk.version>
<artemis.version>2.20.0</artemis.version>
<aspectj.version>1.9.7</aspectj.version>
<assertj.version>3.22.0</assertj.version>
<commons-codec.version>1.15</commons-codec.version>
<hibernate.version>5.6.10.Final</hibernate.version>
<jackson.version>2.13.4</jackson.version>
<jakarta-servlet.version>5.0.0</jakarta-servlet.version>
<junit.version>4.13.2</junit.version>
<logback.version>1.2.11</logback.version>
<mysql.version>8.0.31</mysql.version>
<slf4j.version>1.7.36</slf4j.version>
<spring.version>5.3.23</spring.version>
<tomcat.version>9.0.68</tomcat.version>
<!-- 300+个版本定义 -->
</properties>
<!-- 依赖管理 -->
<dependencyManagement>
<dependencies>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-web</artifactId>
<version>${revision}</version>
</dependency>
<dependency>
<groupId>org.apache.tomcat.embed</groupId>
<artifactId>tomcat-embed-core</artifactId>
<version>${tomcat.version}</version>
</dependency>
<!-- ... -->
</dependencies>
</dependencyManagement>
2. 起步依赖本身很简单
spring-boot-starter-web.pom:
<?xml version="1.0" encoding="UTF-8"?>
<project>
<modelVersion>4.0.0</modelVersion>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-web</artifactId>
<version>2.7.8</version>
<dependencies>
<!-- 1. Web核心 -->
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter</artifactId>
</dependency>
<!-- 2. JSON处理 -->
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-json</artifactId>
</dependency>
<!-- 3. Tomcat服务器 -->
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-tomcat</artifactId>
</dependency>
<!-- 4. Spring MVC -->
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-webmvc</artifactId>
</dependency>
<!-- 5. 验证 -->
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-validation</artifactId>
</dependency>
</dependencies>
</project>
注意:起步依赖不包含实际代码,只是依赖的集合。
3. 层层传递的依赖
你的项目
↓
spring-boot-starter-web
├── spring-boot-starter
│ ├── spring-boot
│ ├── spring-boot-autoconfigure
│ ├── spring-core
│ ├── spring-context
│ ├── spring-aop
│ ├── spring-expression
│ ├── spring-jcl
│ └── logback-classic
├── spring-boot-starter-json
│ ├── jackson-databind
│ ├── jackson-core
│ ├── jackson-datatype-jsr310
│ └── jackson-module-parameter-names
├── spring-boot-starter-tomcat
│ ├── tomcat-embed-core
│ ├── tomcat-embed-el
│ └── tomcat-embed-websocket
├── spring-webmvc
│ ├── spring-web
│ └── spring-beans
└── spring-boot-starter-validation
├── hibernate-validator
└── jakarta.validation-api
常用起步依赖详解
| Starter | 包含内容 | 典型用途 |
|---|---|---|
| spring-boot-starter-web | Tomcat + Spring MVC + Jackson | Web应用、REST API |
| spring-boot-starter-data-jpa | Hibernate + Spring Data JPA | 数据库操作 |
| spring-boot-starter-security | Spring Security | 安全认证授权 |
| spring-boot-starter-test | JUnit + Mockito + AssertJ | 单元测试 |
| spring-boot-starter-actuator | 监控端点 | 应用监控 |
| spring-boot-starter-cache | 缓存抽象 | 缓存功能 |
| spring-boot-starter-mail | JavaMail | 邮件发送 |
| spring-boot-starter-aop | Spring AOP + AspectJ | 面向切面编程 |
| spring-boot-starter-websocket | WebSocket支持 | 实时通信 |
| spring-boot-starter-batch | Spring Batch | 批处理 |
自定义起步依赖
案例:自定义短信服务Starter
1. 创建starter项目结构:
my-sms-starter/
├── src/
│ ├── main/
│ │ ├── java/com/example/sms/
│ │ │ ├── SmsAutoConfiguration.java
│ │ │ ├── SmsProperties.java
│ │ │ ├── SmsService.java
│ │ │ └── SmsTemplate.java
│ │ └── resources/
│ │ └── META-INF/
│ │ └── spring.factories
│ └── test/
└── pom.xml
2. pom.xml配置:
<?xml version="1.0" encoding="UTF-8"?>
<project>
<modelVersion>4.0.0</modelVersion>
<groupId>com.example</groupId>
<artifactId>my-sms-spring-boot-starter</artifactId>
<version>1.0.0</version>
<parent>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-parent</artifactId>
<version>2.7.8</version>
</parent>
<dependencies>
<!-- 必须依赖 -->
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-configuration-processor</artifactId>
<optional>true</optional>
</dependency>
<!-- 短信SDK -->
<dependency>
<groupId>com.aliyun</groupId>
<artifactId>aliyun-java-sdk-core</artifactId>
<version>4.6.3</version>
</dependency>
</dependencies>
</project>
3. 配置类:
// SmsProperties.java - 配置属性
@ConfigurationProperties(prefix = "sms")
public class SmsProperties {
private String accessKeyId;
private String accessKeySecret;
private String signName;
private String templateCode;
// getters and setters
}
// SmsAutoConfiguration.java - 自动配置
@Configuration
@EnableConfigurationProperties(SmsProperties.class)
@ConditionalOnClass(SmsService.class) // 当SmsService在类路径时才生效
@ConditionalOnProperty(prefix = "sms", value = "enabled", matchIfMissing = true)
public class SmsAutoConfiguration {
@Bean
@ConditionalOnMissingBean
public SmsService smsService(SmsProperties properties) {
return new SmsService(properties);
}
@Bean
@ConditionalOnMissingBean
public SmsTemplate smsTemplate(SmsService smsService) {
return new SmsTemplate(smsService);
}
}
4. spring.factories文件:
# META-INF/spring.factories
org.springframework.boot.autoconfigure.EnableAutoConfiguration=\
com.example.sms.SmsAutoConfiguration
5. 在其他项目中使用:
<!-- 引入自定义starter -->
<dependency>
<groupId>com.example</groupId>
<artifactId>my-sms-spring-boot-starter</artifactId>
<version>1.0.0</version>
</dependency>
# application.yml
sms:
enabled: true
access-key-id: your-access-key
access-key-secret: your-secret
sign-name: 公司签名
template-code: SMS_123456
// 直接注入使用
@RestController
public class UserController {
@Autowired
private SmsTemplate smsTemplate;
@PostMapping("/send-code")
public String sendCode(@RequestParam String phone) {
String code = generateCode();
smsTemplate.sendVerifyCode(phone, code);
return "验证码已发送";
}
}
自动配置原理
1. @SpringBootApplication注解
@SpringBootApplication
public class MyApplication {
public static void main(String[] args) {
SpringApplication.run(MyApplication.class, args);
}
}
// 展开后:
@SpringBootConfiguration
@EnableAutoConfiguration // 关键!
@ComponentScan
public class MyApplication { ... }
2. @EnableAutoConfiguration原理
@Target(ElementType.TYPE)
@Retention(RetentionPolicy.RUNTIME)
@Documented
@Inherited
@AutoConfigurationPackage
@Import(AutoConfigurationImportSelector.class) // 核心!
public @interface EnableAutoConfiguration { ... }
AutoConfigurationImportSelector的工作流程:
1. 扫描所有jar包的META-INF/spring.factories
2. 读取key为EnableAutoConfiguration的配置类
3. 根据@Conditional注解判断是否需要加载
4. 加载符合条件的配置类
5. 注册Bean到Spring容器
3. 条件注解(@Conditional)
| 注解 | 作用 | 示例 |
|---|---|---|
@ConditionalOnClass |
类路径存在才生效 | @ConditionalOnClass(DataSource.class) |
@ConditionalOnMissingClass |
类路径不存在才生效 | |
@ConditionalOnBean |
容器中有Bean才生效 | @ConditionalOnBean(DataSource.class) |
@ConditionalOnMissingBean |
容器中没有Bean才生效 | |
@ConditionalOnProperty |
配置属性满足条件 | @ConditionalOnProperty(name="sms.enabled") |
@ConditionalOnWebApplication |
是Web应用才生效 | |
@ConditionalOnNotWebApplication |
不是Web应用才生效 | |
@ConditionalOnExpression |
SpEL表达式 | @ConditionalOnExpression("#{environment['spring.datasource.url'] != null}") |
查看自动配置报告
1. 开启调试模式
# application.yml
debug: true
启动时会输出:
============================
CONDITIONS EVALUATION REPORT
============================
Positive matches: # 匹配的自动配置
-----------------
DataSourceAutoConfiguration matched:
- @ConditionalOnClass found required classes 'javax.sql.DataSource', 'org.springframework.jdbc.datasource.embedded.EmbeddedDatabaseType' (OnClassCondition)
- @ConditionalOnMissingBean (types: javax.sql.DataSource; SearchStrategy: all) did not find any beans (OnBeanCondition)
Negative matches: # 未匹配的自动配置
-----------------
ActiveMQAutoConfiguration:
Did not match:
- @ConditionalOnClass did not find required class 'javax.jms.ConnectionFactory' (OnClassCondition)
2. 查看所有自动配置
# 启动时添加参数
java -jar myapp.jar --debug
或在代码中:
@SpringBootApplication
public class MyApplication {
public static void main(String[] args) {
SpringApplication app = new SpringApplication(MyApplication.class);
app.setAdditionalProfiles("debug");
app.run(args);
}
}
起步依赖的优势
1. 简化配置
<!-- 传统方式:20+个依赖 -->
<!-- Spring Boot:1个starter -->
2. 版本统一管理
<!-- 传统:容易版本冲突 -->
<dependency>
<groupId>com.fasterxml.jackson.core</groupId>
<artifactId>jackson-databind</artifactId>
<version>2.12.3</version> <!-- 版本A -->
</dependency>
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-web</artifactId>
<version>5.3.8</version> <!-- 版本B,可能不兼容 -->
</dependency>
<!-- Spring Boot:统一管理,保证兼容 -->
3. 自动配置
// 传统:手动配置Bean
@Configuration
public class DataSourceConfig {
@Bean
public DataSource dataSource() {
// 一堆配置
}
}
// Spring Boot:自动配置
// 只需在application.yml中配置
spring:
datasource:
url: jdbc:mysql://localhost:3306/test
username: root
password: 123456
4. 快速启动
# 传统:配置半天才能跑
# Spring Boot:5分钟一个项目
🔧 实际使用技巧
1. 排除不需要的依赖
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-web</artifactId>
<exclusions>
<!-- 排除Tomcat,使用Jetty -->
<exclusion>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-tomcat</artifactId>
</exclusion>
</exclusions>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-jetty</artifactId>
</dependency>
2. 查看依赖树
# 查看依赖关系
mvn dependency:tree
# 查看特定依赖
mvn dependency:tree -Dincludes=com.fasterxml.jackson
# Gradle
./gradlew dependencies
3. 覆盖默认版本
<!-- 在pom.xml中覆盖 -->
<properties>
<mysql.version>8.0.33</mysql.version>
<jackson.version>2.14.0</jackson.version>
</properties>
4. 自定义起步依赖
<!-- 公司内部通用starter -->
<dependency>
<groupId>com.mycompany</groupId>
<artifactId>mycompany-spring-boot-starter</artifactId>
<version>1.0.0</version>
</dependency>
性能优化
1. 排除不必要的自动配置
@SpringBootApplication(exclude = {
DataSourceAutoConfiguration.class, // 如果没有数据库
SecurityAutoConfiguration.class, // 如果不需要安全
MailSenderAutoConfiguration.class // 如果不需要邮件
})
public class MyApplication { ... }
2. 懒加载
# application.yml
spring:
main:
lazy-initialization: true # 启动时不初始化所有Bean
3. 指定扫描范围
@SpringBootApplication(scanBasePackages = "com.example.myapp")
public class MyApplication { ... }
企业级最佳实践
1. 分层架构的依赖管理
<!-- parent pom.xml -->
<dependencyManagement>
<dependencies>
<!-- 公司统一的版本管理 -->
<dependency>
<groupId>com.mycompany</groupId>
<artifactId>company-bom</artifactId>
<version>1.0.0</version>
<type>pom</type>
<scope>import</scope>
</dependency>
</dependencies>
</dependencyManagement>
<!-- module pom.xml -->
<dependencies>
<!-- 业务模块 -->
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-web</artifactId>
</dependency>
<dependency>
<groupId>com.mycompany</groupId>
<artifactId>company-common-starter</artifactId>
</dependency>
</dependencies>
2. 多环境配置
# application-dev.yml
spring:
datasource:
url: jdbc:h2:mem:testdb
# application-prod.yml
spring:
datasource:
url: jdbc:mysql://prod-db:3306/app
hikari:
maximum-pool-size: 20
3. 监控和健康检查
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-actuator</artifactId>
</dependency>
<dependency>
<groupId>io.micrometer</groupId>
<artifactId>micrometer-registry-prometheus</artifactId>
</dependency>
常见问题
1. 版本冲突
# 查看冲突
mvn dependency:tree -Dverbose
# 解决:排除冲突的依赖
<exclusions>
<exclusion>
<groupId>com.google.guava</groupId>
<artifactId>guava</artifactId>
</exclusion>
</exclusions>
2. 自动配置不生效
// 检查条件
@ConditionalOnClass(SomeClass.class) // 类路径是否有?
@ConditionalOnProperty("some.property") // 配置属性是否有?
3. 启动慢
# 使用Spring Boot DevTools热重启
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-devtools</artifactId>
<optional>true</optional>
</dependency>
总结:Spring Boot起步依赖是约定优于配置思想的完美体现。它通过:
- 统一版本管理:解决依赖冲突
- 自动配置:减少样板代码
- 条件装配:智能加载组件
- 模块化设计:按需引入功能
核心价值:让开发者专注于业务逻辑,而不是基础设施配置。
更多推荐



所有评论(0)