文章目录
- 前言
-
- [1. 入口:`@SpringBootApplication`](#1. 入口:
@SpringBootApplication) - [2. 核心开关:`@EnableAutoConfiguration`](#2. 核心开关:
@EnableAutoConfiguration) - [3. 读取自动配置类列表](#3. 读取自动配置类列表)
- [4. 自动配置类本质是什么?](#4. 自动配置类本质是什么?)
- [5. 条件判断:为什么有些配置生效,有些不生效?](#5. 条件判断:为什么有些配置生效,有些不生效?)
- [6. 完整执行链路](#6. 完整执行链路)
- [7. 举个例子:Redis 自动配置](#7. 举个例子:Redis 自动配置)
- [8. 怎么看哪些自动配置生效?](#8. 怎么看哪些自动配置生效?)
- [9. 一句话总结](#9. 一句话总结)
- [1. 入口:`@SpringBootApplication`](#1. 入口:
前言
下面按源码链路拆:
1. 入口:@SpringBootApplication
它本质是三个注解的组合:
java
@SpringBootConfiguration
@EnableAutoConfiguration
@ComponentScan
官方也明确说,@SpringBootApplication 等价于启用配置类、自动配置、组件扫描。(Home)
2. 核心开关:@EnableAutoConfiguration
它的源码核心是:
java
@AutoConfigurationPackage
@Import(AutoConfigurationImportSelector.class)
public @interface EnableAutoConfiguration {
}
关键在这一句:
java
@Import(AutoConfigurationImportSelector.class)
也就是说:
自动配置真正的入口是
AutoConfigurationImportSelector
官方说明:自动配置会根据 classpath 和你已经定义的 Bean 来推测需要配置什么。(Home)
3. 读取自动配置类列表
Spring Boot 3.x 主要从这个文件读取:
text
META-INF/spring/org.springframework.boot.autoconfigure.AutoConfiguration.imports
里面类似:
text
org.springframework.boot.autoconfigure.web.servlet.WebMvcAutoConfiguration
org.springframework.boot.autoconfigure.jdbc.DataSourceAutoConfiguration
org.springframework.boot.autoconfigure.data.redis.RedisAutoConfiguration
org.springframework.boot.autoconfigure.jackson.JacksonAutoConfiguration
官方文档也说明,自动配置类可以放在外部 jar 中,并通过 META-INF/spring/*.imports 被发现。(Home)
4. 自动配置类本质是什么?
自动配置类其实就是特殊的配置类:
java
@AutoConfiguration
@ConditionalOnClass(DataSource.class)
@EnableConfigurationProperties(DataSourceProperties.class)
public class DataSourceAutoConfiguration {
}
@AutoConfiguration 本质接近:
java
@Configuration(proxyBeanMethods = false)
官方 API 说明:自动配置类是普通 @Configuration,区别是 proxyBeanMethods=false,并且通常配合 @ConditionalOnClass、@ConditionalOnMissingBean。(Home)
5. 条件判断:为什么有些配置生效,有些不生效?
核心靠一堆 @Conditional... 注解:
java
@ConditionalOnClass
@ConditionalOnMissingBean
@ConditionalOnBean
@ConditionalOnProperty
@ConditionalOnWebApplication
比如:
java
@Bean
@ConditionalOnMissingBean
public ObjectMapper objectMapper() {
return new ObjectMapper();
}
意思是:
如果你自己没有定义
ObjectMapper,Spring Boot 才帮你创建一个。
所以自动配置的原则是:
你没配,我帮你配;你自己配了,我就让位。
6. 完整执行链路
js
SpringApplication.run()
↓
加载主启动类
↓
解析 @SpringBootApplication
↓
发现 @EnableAutoConfiguration
↓
@Import(AutoConfigurationImportSelector.class)
↓
读取 AutoConfiguration.imports
↓
拿到一批自动配置类
↓
按条件筛选
↓
把符合条件的配置类导入容器
↓
执行其中的 @Bean 方法
↓
生成 Bean
7. 举个例子:Redis 自动配置
你引入:
xml
spring-boot-starter-data-redis
classpath 中出现 Redis 相关类。
Spring Boot 发现:
java
@ConditionalOnClass(RedisOperations.class)
成立。
然后检查:
java
@ConditionalOnMissingBean(RedisConnectionFactory.class)
如果你没自己定义,它就自动创建:
java
RedisConnectionFactory
RedisTemplate
StringRedisTemplate
所以你才能直接:
java
@Autowired
private StringRedisTemplate stringRedisTemplate;
8. 怎么看哪些自动配置生效?
启动时加:
bash
--debug
或者配置:
properties
debug=true
会看到 Conditions Evaluation Report。
官方文档也建议通过 --debug、-Ddebug 或 Actuator 的 conditions endpoint 查看哪些自动配置被打开。(Home)
9. 一句话总结
Spring Boot 自动配置 = @EnableAutoConfiguration 通过 AutoConfigurationImportSelector 读取 AutoConfiguration.imports 中的配置类,再根据 @Conditional 条件决定哪些配置类和 Bean 真正生效。