【Spring源码15】SpringBoot自动配置万字源码拆解!SPI机制+条件注解+自动装配全流程(面试核心)
🔥 Spring全家桶源码连载系列(SpringBoot核心篇)
上一篇第14篇,我们搞懂了 SpringBoot 启动流程、约定大于配置、Starter 基础原理。
但所有开发者最大的疑问始终是:
为什么SpringBoot引入一个starter就能自动配置好所有Bean?
自动配置到底是怎么生效的?底层源码链路是什么?
为什么有的组件自动创建,有的不创建?条件注解如何工作?
可以这么说:弄懂了自动配置,才算真正弄懂了SpringBoot。
自动配置是 SpringBoot 的灵魂核心,也是面试必问、底层最难、工作最常用的核心知识点。
本篇带大家手撕全套自动配置源码:SPI扩展机制 → 自动配置加载流程 → 条件注解匹配 → Bean动态装配 → 手动覆盖默认配置,全网最透彻、无废话干货解析!
一、自动配置核心前置认知
1.1 什么是SpringBoot自动配置?
定义:SpringBoot 根据项目中引入的 Maven 依赖,自动推断运行环境,在容器启动时自动加载对应的配置类、自动创建通用Bean、自动整合框架环境,无需开发者手动配置。
简单一句话:你引入什么依赖,SpringBoot就帮你自动配好什么环境。
1.2 为什么需要自动配置?
回顾 SSM 开发:
-
使用 SpringMVC 需要手动配置视图解析器、拦截器、参数解析器
-
使用 MyBatis 需要手动配置 SqlSessionFactory、MapperScanner
-
使用事务需要手动配置事务管理器、开启事务注解
而 SpringBoot 自动配置,把所有通用模板配置全部预写死在框架内部,项目启动时按需加载,彻底消灭重复配置。
1.3 自动配置的两大核心基石
SpringBoot 自动配置能跑通,完全依赖两大机制:
-
Java SPI / Spring SPI 扩展机制:找到所有自动配置类
-
条件注解机制:判断是否需要创建 Bean、是否生效配置
二、自动配置入口:@EnableAutoConfiguration 深度拆解
我们上篇讲过,@SpringBootApplication 核心包含三大注解,其中 @EnableAutoConfiguration 就是自动配置的开关。
点开注解源码,底层藏着两个关键注解。
2.1 @AutoConfigurationPackage(自动扫描包)
作用:自动扫描启动类所在包及子包,将业务组件(Controller/Service/Component)注册到容器。
这也是为什么 SpringBoot 启动类必须放在根包的原因,否则无法扫描到业务Bean。
2.2 @Import(AutoConfigurationImportSelector.class)(核心灵魂)
这是自动配置的真正入口。
通过 @Import 导入 AutoConfigurationImportSelector 选择器类,该类实现了 Spring 的 DeferredImportSelector 接口。
在容器刷新阶段,会自动执行该选择器的核心方法,加载所有自动配置类。
三、SPI机制:自动配置类是怎么被找到的?
3.1 什么是SPI?
SPI(Service Provider Interface):服务提供者扩展机制。
核心思想:接口定义规范,配置文件指定实现类,程序动态加载实现类,实现解耦与拓展。
SpringBoot 基于 SPI 思想,实现了自定义 Spring SPI,用来加载海量自动配置类。
3.2 自动配置配置文件位置
在 SpringBoot 源码包中,存在核心配置文件:
META-INF/spring/org.springframework.boot.autoconfigure.AutoConfiguration.imports
文件内部,存放了SpringBoot所有内置自动配置类全路径,多达上百个:
-
WebMvcAutoConfiguration(Web环境自动配置)
-
DataSourceAutoConfiguration(数据源自动配置)
-
TransactionAutoConfiguration(事务自动配置)
-
JacksonAutoConfiguration(JSON序列化自动配置)
-
ServletWebServerFactoryAutoConfiguration(内嵌Tomcat自动配置)
3.3 SPI加载流程
-
项目启动,触发 AutoConfigurationImportSelector 执行
-
通过 SpringFactoriesLoader 加载 resources 下的 imports 配置文件
-
读取所有预定义的自动配置类全限定名
-
去重、过滤、排序,得到候选自动配置类集合
-
将这些配置类导入 Spring 容器,当作配置类解析
核心结论:SpringBoot 启动时,默认加载上百个自动配置类,再通过条件注解筛选是否生效。
四、条件注解:决定配置生不生效的关键(面试必考)
如果所有自动配置类全部生效,会造成大量冗余Bean、冲突Bean。
所以 SpringBoot 设计了条件注解体系:满足条件才创建Bean,不满足直接跳过。
所有自动配置类,全部基于条件注解实现按需加载。
4.1 核心条件注解大全
-
@ConditionalOnClass:classpath下存在指定类,才生效配置
-
@ConditionalOnMissingClass:classpath下不存在指定类,才生效
-
@ConditionalOnBean:容器中存在指定Bean,才生效
-
@ConditionalOnMissingBean:容器中没有指定Bean,才生效(最常用)
-
@ConditionalOnProperty:配置文件存在指定配置,才生效
-
@ConditionalOnWebApplication:当前是Web环境,才生效
-
@ConditionalOnResource:存在指定资源文件,才生效
4.2 核心原理:按需装配
举个典型例子:WebMvcAutoConfiguration
该配置类上加了 @ConditionalOnWebApplication,只有项目引入web依赖、属于web环境时,才会加载SpringMVC自动配置。
非web项目,直接跳过该配置类,不加载无效Bean。
4.3 @ConditionalOnMissingBean 核心机制(重中之重)
这是 SpringBoot 默认配置与自定义配置优先级 的核心关键!
规则:
-
如果开发者手动自定义了Bean,容器中已存在该Bean
-
SpringBoot 自带的自动配置Bean 不会创建
-
如果开发者没有自定义,SpringBoot 自动创建默认Bean
一句话总结:用户优先,框架兜底。
这就是为什么我们自定义配置类可以覆盖SpringBoot默认配置的底层原理!
五、完整自动配置执行源码链路(逐步骤吃透)
结合前面学的 IoC 容器刷新流程,串联完整自动配置执行顺序,面试可直接口述满分。
步骤1:启动类标记 @EnableAutoConfiguration
开启自动配置开关,导入 AutoConfigurationImportSelector 选择器。
步骤2:容器刷新阶段执行选择器方法
Spring 容器 refresh() 过程中,处理 @Import 导入的选择器,触发 selectImports() 方法。
步骤3:SPI加载所有自动配置类
读取 META-INF 下的 imports 文件,加载全部自动配置类全限定名,得到候选配置列表。
步骤4:过滤、去重、排除指定配置
根据注解 exclude 属性、配置文件排除配置,剔除不需要加载的自动配置类。
步骤5:将剩余配置类导入容器,当作配置类解析
Spring 将这些自动配置类,和我们自己写的 @Configuration 配置类同等对待。
步骤6:解析配置类中的 @Bean 方法
遍历自动配置类,读取内部所有 @Bean 注解方法。
步骤7:条件注解匹配校验
执行每个Bean的条件注解判断,满足条件则创建Bean,不满足直接跳过。
步骤8:自动Bean注册到IoC容器
生效的默认Bean完成实例化、初始化,存入单例池,完成自动装配。
至此,SpringBoot自动配置全过程结束!
六、实战案例:WebMvcAutoConfiguration 源码解析
我们以最常用的Web自动配置类为例,落地验证上述原理。
WebMvcAutoConfiguration 核心功能:自动配置SpringMVC全套环境
-
自动配置拦截器、转换器、格式化器
-
自动配置JSON参数解析器、消息转换器
-
自动配置视图控制器、静态资源映射规则
-
自动配置跨域、异常基础适配规则
该类严格遵循条件注解规则:仅Web环境生效,且用户未自定义MVC配置时,默认启用框架配置。
当我们手动实现 WebMvcConfigurer 自定义配置时,不会完全覆盖默认配置,而是拓展追加配置,这也是SpringBoot的人性化设计。
七、自动配置核心拓展规则(面试高频坑点)
7.1 自定义配置 & 自动配置优先级
自定义Bean > SpringBoot自动配置Bean
底层依托 @ConditionalOnMissingBean 实现,用户手动定义的Bean优先注册,框架默认Bean失效,完美实现自定义覆盖默认。
7.2 如何关闭指定自动配置?
在启动类注解中排除指定自动配置类:
@SpringBootApplication(exclude = {DataSourceAutoConfiguration.class})
适用于需要手动全权接管数据源、事务等特殊场景。
7.3 自动配置的核心优势总结
-
零配置开箱即用,极大提升开发效率
-
按需加载,无冗余Bean,不浪费资源
-
用户配置优先,拓展性极强
-
统一框架底层配置规范,避免人为配置错误
八、高频面试真题满分必背
1、SpringBoot自动配置原理?
SpringBoot自动配置基于@EnableAutoConfiguration注解开启,底层通过AutoConfigurationImportSelector结合Spring SPI机制,加载META-INF目录下的所有自动配置类。再通过各类条件注解按需匹配环境,在用户未自定义Bean的情况下,自动创建框架默认Bean,完成全套环境自动装配,实现零配置开发。
2、SPI机制在SpringBoot中的作用?
SPI是SpringBoot自动配置的核心加载机制,通过读取固定配置文件中的自动配置类全路径,批量加载框架预定义的配置类,实现配置类的动态发现与加载,解耦框架与业务,支撑自动装配能力。
3、@ConditionalOnMissingBean的作用?
该条件注解表示仅当容器中不存在对应Bean时,才创建当前Bean。保证开发者自定义的Bean优先级高于框架默认Bean,实现用户配置覆盖框架默认配置,兼顾开箱即用与自定义拓展能力。
4、为什么引入starter就能自动配置?
引入starter后,项目classpath中会出现对应框架依赖类,触发自动配置类的@ConditionalOnClass条件匹配,使对应的自动配置类生效,自动创建相关功能Bean,无需手动配置即可使用对应功能。
5、如何实现SpringBoot自定义starter?
自定义starter需要两步:1、创建自动配置类,通过条件注解定义Bean加载规则;2、在META-INF/imports文件中配置自定义自动配置类路径,项目引入该starter后,即可通过SPI机制自动加载配置,实现自定义场景的自动装配。
九、本篇总结 & 下期预告
本篇总结
本篇彻底击穿 SpringBoot 最核心的自动配置原理,打通底层核心逻辑:
-
掌握自动配置入口注解与底层核心类
-
吃透 SPI 扩展机制的加载原理与作用
-
精通全套条件注解的匹配规则与实战场景
-
理解用户配置优先、框架兜底的设计思想
-
完整掌握自动配置从加载、筛选、创建到注册的全流程
至此,你已经彻底搞懂 SpringBoot「零配置」的底层真相!
下期预告
下一篇第十六篇,我们拆解 SpringBoot内嵌Tomcat源码全解!搞懂为什么不用外置Tomcat、内嵌容器启动流程、端口绑定、Web容器初始化底层原理,补齐SpringBoot Web核心最后一块短板!
💡 往期推荐 & 系列连载
本Spring全家桶源码系列循序渐进、层层拆解,吃透底层原理,搞定所有面试与工作疑难!
更多推荐

所有评论(0)