目标:你能从
SpringApplication.run()讲到"哪些 AutoConfiguration 生效/为什么不生效",并且在遇到启动失败、Bean 冲突、配置不生效时有一套稳定的排查路径。
1. Spring Boot 的价值:把"约定"落成"可组合的配置模块"
Boot 本质不是魔法,而是把一堆常见的 Spring 配置拆成模块:
- 一堆
@Configuration(自动配置类) - 每个配置类通过
@Conditional...决定是否生效 - 由
spring.factories/AutoConfiguration.imports把模块串起来
你理解了这一点,就能把"为什么我加了依赖就自动有了 Bean"解释清楚。
2. 启动主线:SpringApplication.run() 做了哪些事
抓住 4 个阶段:
- 准备环境 :读配置文件、系统属性、命令行参数,生成
Environment - 创建容器 :
ApplicationContext(Web/非 Web) - 加载 Bean 定义 :扫描
@Configuration、导入自动配置、解析条件 - 刷新容器:实例化单例、完成依赖注入、触发生命周期回调
如果你在面试里只讲"run 会启动容器",会显得不够扎实;你要能把故障定位到具体阶段。
3. 自动装配是怎么"导入"的
不同版本机制略有差异,但主旨一致:
- Spring Boot 会在启动时收集一批自动配置类(AutoConfiguration)
- 再按条件注解判断是否生效
你可以把它理解成:
- "候选配置列表" + "条件过滤器"
3.1 自动配置的典型结构
XxxAutoConfiguration:提供默认 BeanXxxProperties:绑定配置项(@ConfigurationProperties)@ConditionalOnClass:类路径有依赖才装@ConditionalOnMissingBean:你自己定义了就不装(可覆盖默认)
4. 条件注解:决定"生效/不生效"的关键
你需要会解释常见条件:
@ConditionalOnClass/@ConditionalOnMissingClass@ConditionalOnBean/@ConditionalOnMissingBean@ConditionalOnProperty(最常用:配置开关)@ConditionalOnWebApplication
4.1 @ConditionalOnMissingBean 的覆盖模型
这是 Boot 可扩展性的核心:
- 框架提供默认 Bean
- 业务只要定义同类型/同名 Bean,就能覆盖
常见坑:
- 你以为覆盖了,但因为 Bean 的类型/泛型不匹配导致没有覆盖
- 你定义的 Bean 还没被扫描到(包路径、配置类未生效)
5. 配置绑定:@ConfigurationProperties 为什么有时"不生效"
常见原因:
- 配置前缀写错
- 配置文件不在生效的 profile 下
- 没有开启绑定(某些场景需要显式启用/扫描)
排查思路:
- 先确认
Environment里是否有该 key - 再确认 properties 类是否被注册为 Bean
- 再确认字段是否能匹配(命名、类型、嵌套结构)
6. 启动失败/冲突:一套可复用排错方法论
6.1 BeanDefinition 冲突(同名 Bean)
- 现象:
BeanDefinitionOverrideException或启动时提示重复 - 根因:
- 你引入了两个 starter 各自提供同名 Bean
- 你自己定义了与自动配置同名 Bean
- 处理:
- 改名或排除某个自动配置
- 用
@Primary/@Qualifier解决注入歧义(但不解决同名定义冲突)
6.2 NoSuchBeanDefinitionException
- 现象:注入失败
- 根因:自动配置没生效 / 组件没扫描到 / 条件没满足
- 排查:
- 看依赖是否存在(
@ConditionalOnClass) - 看配置开关是否打开(
@ConditionalOnProperty) - 看你是否在正确的包扫描路径下
- 看依赖是否存在(
6.3 配置不生效(你改了 yml 但没效果)
- 先确认:
- 是不是启动了另一个 profile
- 有没有被命令行/环境变量覆盖
- 有没有多个配置文件同 key 被后者覆盖
7. 线上/本地快速定位技巧
-
打开条件评估报告(Condition Evaluation Report)思路:
- 你要知道"为什么某个 AutoConfiguration 没生效"
- 核心是查看条件是否匹配
-
关注日志关键字:
- auto-config report
- matched / did not match
-
最小化复现:
- 新建一个干净工程只保留相关 starter + 一段配置
- 先让自动配置生效再逐步加回其它依赖
8. 面试背诵稿(45 秒)
Spring Boot 的自动装配本质是:启动时导入一批 AutoConfiguration(本质是 @Configuration),然后通过 @ConditionalOnClass/@ConditionalOnProperty/@ConditionalOnMissingBean 等条件注解过滤生效。
SpringApplication.run 主要经历准备环境、创建容器、加载 Bean 定义与刷新容器几个阶段。
排错时我会先确认配置是否进入 Environment,再看对应的自动配置类是否被导入以及条件是否匹配;遇到 Bean 冲突就考虑排除某个自动配置或调整 Bean 定义,遇到注入缺失就从依赖类路径、配置开关、包扫描范围三条线排。