一个朋友去面试,回来以后跟我吐槽:“Spring Boot 我用了五六年,结果面试官问我自动配置原理,我差点把自己说自动关机了。”
我问他:“你怎么回答的?”
他说:“Spring Boot 会自动帮我们配置 Bean。”
“然后呢?”
“然后……它就自动配置了啊。”
这就像面试官问你:“外卖为什么能送到你家?” 你回答:“因为外卖小哥会送过来。” 不能说错,但基本等于没回答。
Spring Boot 自动配置真正有意思的地方,并不是“自动”两个字,而是:
- Spring Boot 到底怎么知道要配置什么?
- 为什么有些配置会生效,有些不会?
- 为什么我们自己定义一个 Bean,它又经常不自动配置了?
今天我们就把 Spring Boot 自动配置 这套机制彻底拆开。
先从一个奇怪的现象说起
假设我们创建一个普通的 Spring Boot Web 项目,引入:

然后写:

神奇的事情发生了:我们没有手动创建 DispatcherServlet,没有自己配置 JSON 转换器,也没有像传统 Spring MVC 项目那样写一大堆 XML,但项目启动以后,Web 应用就是能跑。
为什么?可以把 Spring Boot 想象成一家“智能酒店”。你走进酒店:
- 只要前台发现“这位客人订的是豪华套房”,系统就自动准备拖鞋、浴袍、洗漱用品、咖啡机。
- 但如果你自己说“咖啡机不用酒店准备,我自己带了”,酒店就不再给你放一台。
这就是 Spring Boot 自动配置最核心的设计思想:根据当前环境判断需要什么,在满足条件时提供默认配置;如果开发者已经自己配置,则尽量让开发者的配置优先。
故事的入口:@SpringBootApplication
Spring Boot 项目最熟悉的注解就是 @SpringBootApplication,很多人每天都写,却很少真正点进去看。
它本质上是一个组合注解,其中最重要的几个组成部分可以概括为:
@SpringBootConfiguration
@EnableAutoConfiguration
@ComponentScan
简单整理一下:

所以,如果面试官问“Spring Boot 自动配置从哪里开启”,不要只回答 @SpringBootApplication,更准确的说法应该是:@SpringBootApplication 中包含 @EnableAutoConfiguration,真正负责开启自动配置机制的是 @EnableAutoConfiguration。
到这里,故事才刚刚开始。
@EnableAutoConfiguration 干了什么?
继续往里面看,会发现一个非常重要的机制:@Import(...)。
Spring 的 @Import 大家应该不陌生,它就像酒店前台拿出了一本《酒店服务供应商名单》。Spring Boot 不可能把数据库、Redis、Web、Kafka、RabbitMQ 等所有配置全部写死到你的项目中,它需要先找到:当前有哪些“自动配置类”可以参与配置。
在较新的 Spring Boot 版本中,自动配置候选类主要通过 META-INF/spring/org.springframework.boot.autoconfigure.AutoConfiguration.imports 进行声明。
例如你可能看到类似:
org.springframework.boot.autoconfigure.web.servlet.WebMvcAutoConfiguration
org.springframework.boot.autoconfigure.jdbc.DataSourceAutoConfiguration
org.springframework.boot.autoconfigure.data.redis.RedisAutoConfiguration
这些就是候选的自动配置类。
注意一个非常重要的词:候选。找到它们,并不意味着全部加载。否则你明明没有 Redis,Spring Boot 还非要给你创建 Redis 相关 Bean,那就不是自动配置,而是“自动添乱”了。
所以接下来还有一个关键机制:条件装配。
真正的灵魂:@Conditional
Spring Boot 自动配置最精髓的地方,我认为不是“找到配置类”,而是:判断配置类到底该不该生效。这件事情主要依靠各种 @Conditional 条件注解完成。
就像酒店前台拿着服务清单开始判断:
- “客人有没有订早餐?”
- “房间是不是行政套房?”
- “客人有没有自己带咖啡机?”
- 条件满足,服务开启。
- 条件不满足,直接跳过。
常见条件注解如下:

这里尤其要理解两个:@ConditionalOnClass 和 @ConditionalOnMissingBean,它们基本体现了 Spring Boot 自动配置的两大原则。
为什么引入 Starter 后配置就出现了?
我们继续用酒店的故事。你原本只是住普通房间,酒店不会准备婴儿床;后来你告诉酒店“我带了一个宝宝”,酒店系统发现条件满足,于是自动安排婴儿床。
Spring Boot 也是一样。例如项目没有 JDBC 相关依赖时,数据库自动配置没有必要生效,但当你引入:

classpath 中就出现了 JDBC、数据源等相关类,此时某些 @ConditionalOnClass(...) 条件成立,对应自动配置才有机会继续执行。
所以我们经常说:Starter 负责依赖整合,AutoConfiguration 负责自动配置,这两个概念不能完全混为一谈。
- Starter 更像是“套餐依赖”。
- AutoConfiguration 更像是“套餐到齐以后,厨师按照条件自动做菜”。
为什么自己定义 Bean 后,Spring Boot 经常就不管了?
这是面试中非常容易继续追问的一点。例如某个自动配置大致存在这样的逻辑:

意思非常简单:容器里没有 XxxService,我帮你创建。
如果你自己已经配置:

那么 @ConditionalOnMissingBean 条件就不成立,Spring Boot 默认配置自然退出。这也是 Spring Boot 非常重要的设计理念:约定优于配置,但约定不能剥夺开发者的控制权。
Spring Boot 可以给你默认答案,但你仍然可以修改答案,这就是所谓的自动配置的“退让机制”。所以自动配置不是 Spring Boot 强行帮你配置,而是在你没有明确配置时,Spring Boot 根据环境给你一个合理默认值。理解这个区别非常重要。
application.yml 又是怎么影响自动配置的?
这时候朋友又问:“那我在 application.yml 里面写的配置,是怎么跑到这些 Bean 里面去的?”
比如:

或者:

Spring Boot 中还有一个非常重要的角色:配置属性绑定。
大量自动配置都会配合 @ConfigurationProperties 使用,把:
application.yml
application.properties
- 环境变量
- 命令行参数
等外部配置绑定到对应的 Properties 对象中。
可以理解成酒店前台已经决定“我要给你准备一间房”,接下来还需要读取你的要求:
- “温度设置多少?”
- “要不要早餐?”
- “床是什么尺寸?”
自动配置负责决定“要不要创建”,配置属性负责决定“创建成什么样”,这是两个不同层次的问题。
完整流程到底是什么?
现在我们把整个过程串起来。假设启动 SpringApplication.run(DemoApplication.class, args);,Spring Boot 自动配置大致可以理解为下面这条链路:

如果面试时能把这条链路讲清楚,基本已经不是“我会用 Spring Boot”的水平,而是开始讲它为什么能工作了。
为什么说自动配置不是组件扫描?
这里还有一个特别容易混淆的地方。有人会说:“自动配置不就是 Spring 扫描 Bean 吗?”
不是。@ComponentScan 和自动配置解决的是不同问题。

比如你自己写:

主要是组件扫描发现它,而 Spring Boot 根据 Web 环境帮你准备 MVC 基础设施,则属于自动配置机制。把这两件事区分开,回答就会清晰很多。
为什么有时候自动配置“不生效”?
实际开发中我们经常碰到:“我依赖明明引入了,为什么 Spring Boot 没自动配置?”
不要第一时间怀疑人生,先检查条件到底有没有满足。Spring Boot 提供了自动配置条件评估信息,可以帮助我们分析:
- 哪些自动配置匹配成功?
- 哪些没有匹配?
- 为什么没有匹配?
例如启动时开启 debug:
debug=true
就可以看到自动配置条件评估相关信息。
你会发现很多类似:
Positive matches
Negative matches
所谓 Positive,就是条件匹配;Negative,就是某些条件没有满足。
所以排查自动配置问题时,不要只盯着 Bean not found,更应该继续追:
- 负责创建这个 Bean 的 AutoConfiguration 是谁?
- 它有哪些 Conditional?
- 到底是哪一个条件失败了?
这才是源码排查思路。
面试官真正想听什么?
如果面试官问:“Spring Boot 自动配置原理是什么?”
很多人的回答是:“Spring Boot 通过 @SpringBootApplication 自动配置 Bean。”
这个答案太薄了。
更完整的思路应该围绕几个关键词展开:

这里最重要的不是死记某一个类名,而是理解整个设计模型:发现候选配置 → 判断环境条件 → 绑定外部参数 → 注册默认 Bean → 尊重用户自定义配置。
最后再回到酒店
故事最后,我又问朋友:“现在知道自动配置是什么了吗?”
他说:“知道了,Spring Boot 就像一家智能酒店。”
你只需要告诉它“我要住店”,它会根据你的订单、房型、会员等级和已有需求,自动决定哪些服务应该开启。
- classpath 中有什么依赖,就像你订了什么套餐;
@Conditional 就像服务规则;
application.yml 就像你的入住偏好;
@ConfigurationProperties 负责把偏好录入系统;
@ConditionalOnMissingBean 则像前台发现:“客人自己带了咖啡机,那我们就不送了。”
所以 Spring Boot 自动配置真正厉害的地方,不是“什么都替你做”,而是:在合适的时候,做合适的默认配置;当你想自己接管时,它又知道什么时候应该退出。
这才是 Spring Boot “开箱即用”背后的真正秘密。
下次面试官再问:“Spring Boot 自动配置原理是什么?”
别急着背注解,从 @SpringBootApplication 开始,一路讲到 @EnableAutoConfiguration、自动配置候选类、条件装配、属性绑定和默认配置退让。
只要这条链路真正理解了,Spring Boot 的很多源码,你会突然发现都能串起来。