Spring自动配置分析

文章目录

  • 前言
    • [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

它本质是三个注解的组合:

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 真正生效。

相关推荐
码事漫谈1 小时前
Deepseek涨价了,前后对比,竟然差这么多
后端
imaol11 小时前
链表 -- 环链表
java·前端·链表
imaol12 小时前
链表 -- 双向链表
java·前端·链表
东风破_2 小时前
大前端手里的 Next.js:从 #root 到 SEO,一份 HTML 的两种命运
前端·后端
IT_陈寒2 小时前
Vue的v-for不听话?我被这个Key的坑整懵了
前端·人工智能·后端
2601_963869952 小时前
【计算机毕业设计】基于Java的相框定制系统的设计与实现
java·开发语言·课程设计
众人皆醒我独醉2 小时前
训练加速实战:Flash Attention、Gradient Checkpointing 与数据流水线
后端·面试·gpu
阿黎梨梨2 小时前
Next.js 全栈开发:从 SPA 的痛点到 SSR 的破局之道
前端·后端
名字还没想好☜2 小时前
Go 的 unsafe.Pointer 实战:零拷贝 []byte↔string 转换与三条铁律
开发语言·后端·golang·go·unsafe
老孙讲技术3 小时前
周末档期厨房爆单,带宽账单也爆了——不是直播难,是主码流 + always 计划在烧钱
后端·物联网