【SpringBoot源码篇-01】SpringBoot自动装配相关知识学习
1、Spring Boot 自动装配核心源码深度剖析
Spring Boot 自动装配(Auto Configuration)是其开箱即用、简化开发的核心能力,本质是:无需手动配置大量 XML/Bean,Spring Boot 自动根据依赖、环境加载对应的配置类并注册 Bean。
本文从核心注解 → 核心流程 → 关键源码 → 工作原理逐层拆解,彻底搞懂自动装配底层逻辑。
一、自动装配的核心入口:@SpringBootApplication
自动装配的起点就是启动类上的这个注解,它是一个复合注解:
@Target(ElementType.TYPE)
@Retention(RetentionPolicy.RUNTIME)
@Documented
@Inherited
@SpringBootConfiguration
@EnableAutoConfiguration // 🔥 自动装配的核心注解
@ComponentScan(excludeFilters = { ... })
public @interface SpringBootApplication {
}
三个核心注解分工:
@SpringBootConfiguration:标记为配置类(本质是@Configuration)@ComponentScan:包扫描,加载自定义 Bean@EnableAutoConfiguration:🔥 开启自动装配(核心)
二、核心注解:@EnableAutoConfiguration 源码
这个注解是自动装配的开关,源码如下:
@Target(ElementType.TYPE)
@Retention(RetentionPolicy.RUNTIME)
@Documented
@Inherited
@AutoConfigurationPackage // 自动配置包
@Import(AutoConfigurationImportSelector.class) // 🔥 核心:导入自动配置选择器
public @interface EnableAutoConfiguration {
}
两个关键组件:
@AutoConfigurationPackage:自动配置主类所在包及子包@Import(AutoConfigurationImportSelector.class):🔥 加载所有自动配置类
三、核心组件:AutoConfigurationImportSelector
这个类是自动装配的大脑,负责筛选、加载所有自动配置类
1. 核心方法:selectImports
@Override
public String[] selectImports(AnnotationMetadata annotationMetadata) {
// 1. 判断是否开启自动装配
if (!isEnabled(annotationMetadata)) {
return NO_IMPORTS;
}
// 2. 加载所有自动配置入口
AutoConfigurationEntry autoConfigurationEntry = getAutoConfigurationEntry(annotationMetadata);
// 3. 返回需要自动装配的全类名数组
return StringUtils.toStringArray(autoConfigurationEntry.getConfigurations());
}
2. 核心方法:getAutoConfigurationEntry
protected AutoConfigurationEntry getAutoConfigurationEntry(AnnotationMetadata annotationMetadata) {
// 1. 获取@EnableAutoConfiguration的属性(exclude等)
AnnotationAttributes attributes = getAttributes(annotationMetadata);
// 🔥 2. 从META-INF/spring/org.springframework.boot.autoconfigure.AutoConfiguration.imports 读取所有自动配置类
List<String> configurations = getCandidateConfigurations(annotationMetadata, attributes);
// 3. 去重
configurations = removeDuplicates(configurations);
// 4. 处理exclude排除的配置类
Set<String> exclusions = getExclusions(annotationMetadata, attributes);
checkExcludedClasses(configurations, exclusions);
configurations.removeAll(exclusions);
// 5. 过滤:根据条件注解(@Conditional)筛选有效配置类
configurations = getConfigurationClassFilter().filter(configurations);
// 6. 发布事件
fireAutoConfigurationImportEvents(configurations, exclusions);
// 7. 返回最终要装配的配置类
return new AutoConfigurationEntry(configurations, exclusions);
}
3. 关键:读取自动配置类

getCandidateConfigurations 会读取 META-INF/spring/org.springframework.boot.autoconfigure.AutoConfiguration.imports 文件:

protected List<String> getCandidateConfigurations(AnnotationMetadata metadata, AnnotationAttributes attributes) {
// 🔥 核心:SpringFactoriesLoader加载自动配置类
List<String> configurations = ImportCandidates.load(AutoConfiguration.class, getBeanClassLoader())
.getCandidates();
Assert.notEmpty(configurations, ...);
return configurations;
}
- Spring Boot 2.7+ 用
ImportCandidates替代了旧的spring.factories - 这个文件里定义了所有官方提供的自动配置类(如
DataSourceAutoConfiguration、RedisAutoConfiguration)
3.1 Spring Factories文件机制
3.1.1 Spring.Factories文件
- 文件定位机制:Spring会扫描所有jar包和类路径下的META-INF/spring.factories文件
- 多位置存储特性:该文件存在于多个jar包中:

3.1.2 键值对配置原理
- 配置格式:采用key-value结构存储自动配置类信息
- 典型配置项:包含如下的自动配置类映射关系:
- org.springframework.boot.autoconfigure.data.mongo.MongoDataAutoConfiguration
- org.springframework.boot.autoconfigure.transaction.TransactionAutoConfiguration
3.1.3 核心加载流程
- 常量定义:通过FACTORIES_RESOURCE_LOCATION常量指定文件路径为"META-INF/spring.factories"
- 缓存机制:使用ConcurrentReferenceMap实现类加载器级别的缓存
- 加载策略:只会加载需要的配置项,通过key进行精确匹配
- 设计特点:支持同一key在多个jar中定义,实现配置的模块化扩展
4、核心步骤
核心步骤1:解析配置类为 BeanDefinition
Spring 后置处理器 ConfigurationClassPostProcessor 将筛选后的自动配置类,统一解析为 BeanDefinition(Bean定义信息),包含类权限、依赖、作用域、初始化方法等元数据。
- beanClass属性:保存bean组件的class对象,用于反射实例化bean
- scope属性:默认是singleton,也可以是prototype
- abstractFlag属性:判断当前bean是否是抽象的
- infer方法:容器推断销毁方法名时使用,当前检测"close"和"shutdown"方法
核心步骤2:注册 BeanDefinition 到注册表
将生成的 BeanDefinition 注册进 BeanDefinitionRegistry 容器注册表,此时仅有定义、无实例对象。
核心步骤3:解析配置类内部 @Bean 方法
递归解析自动配置类中所有 @Bean、@Conditional 注解,批量生成业务Bean的BeanDefinition并再次注册。
核心步骤4:BeanFactory 统一实例化
容器核心工厂 BeanFactory 遍历注册表中所有合法 BeanDefinition,根据定义信息完成:依赖注入、初始化、后置处理。
容器启动完成配置解析后,DefaultListableBeanFactory(核心Bean工厂)遍历所有已注册的BeanDefinition,完成实例化,Spring 高版本已废弃 Class.newInstance() 无参构造实例化方式,底层流程:
1. 解析 BeanDefinition 中的构造器、参数、依赖等元数据;
2. 通过反射构造器实例化(优先有参构造,不再使用老旧的 `Class.newInstance()`)创建Bean原始实例;
3. 完成属性填充、依赖注入、初始化方法执行、Bean后置处理器加工;
4. 将初始化完成的单例Bean实例,存入IOC容器核心的单例池(singletonObjects 大池子);
5. 后续业务直接从IOC容器获取Bean,无需重复创建。
5、ImportSelector 局限性与 DeferredImportSelector 进阶原理

前文核心流程中自动装配的核心入口为 AutoConfigurationImportSelector,该类实现了 DeferredImportSelector 接口,而非普通的 ImportSelector。之所以做这个设计,是因为普通 ImportSelector 存在致命缺陷,无法满足 Spring Boot「用户配置优先、默认配置兜底」的核心设计思想。
5.1 普通 ImportSelector 的核心局限性
普通 ImportSelector 的执行时机极早,在所有配置类、自定义Bean扫描之前就执行导入,存在两大核心问题:
-
无法控制Bean注册顺序:自动配置类会优先于用户自定义的 Bean、配置类注册,执行顺序不可控,容易出现配置覆盖错乱问题
-
难以实现「用户配置优先、默认配置兜底」逻辑:框架默认配置提前注册后,用户后续自定义的同类型 Bean 无法覆盖默认 Bean,违背 Spring Boot 开箱即用、用户自定义优先的设计原则
经典业务示例:SqlSessionFactory 配置冲突问题
MyBatis 自动装配会通过普通选择器逻辑提前注册 SqlSessionFactory 默认 Bean。如果用户手动自定义了SqlSessionFactory 配置类,由于框架默认Bean先注册,容器中已存在对应Bean,用户自定义配置会失效,出现默认配置覆盖用户配置的冲突问题,严重影响业务拓展。
5.2 核心解决方案:DeferredImportSelector(延迟导入选择器)
Spring Boot 专门通过 DeferredImportSelector 解决普通选择器的缺陷,也是自动装配能实现「用户配置优先」的核心底层原理,核心特性如下:
-
延迟导入特性:不再提前执行,在所有常规配置、用户自定义Bean处理完成后,再执行自动配置类导入
-
分组机制:通过
getImportGroup()方法实现配置类分组批量处理,支持有序加载、分类管理自动配置类
-
排序原理:通过分组可以对导入的多个Bean进行自定义排序,例如让第五个Bean排在第三个前面,第七个Bean排在第六个前面
-
隔离特性:分组排序只影响当前配置内部的Bean顺序,不会改变Spring容器中已有Bean的顺序
-
条件判断适配:完美结合
@ConditionalOnBean、@ConditionalOnClass等条件注解,实现「用户有配置则用用户的,无配置则加载默认自动配置」的兜底逻辑
5.3 DeferredImportSelector 核心方法
-
selectImports():核心方法,返回需要导入的自动配置类全类名数组,和普通ImportSelector功能一致
-
getImportGroup():分组核心方法,返回自定义分组处理类,实现配置类分组、有序执行
-
getExclusionFilter():排除过滤器,支持批量剔除指定失效的自动配置类,优化配置加载效率
5.4 DeferredImportSelector 完整执行流程
-
Spring 容器优先扫描并处理所有 用户自定义配置:包括
@Component、@Bean、@Configuration等常规Bean与配置类,完成用户自定义BeanDefinition注册与实例化 -
所有常规配置处理完毕后,容器再统一执行 DeferredImportSelector 的导入逻辑
-
判断是否存在自定义 Group 分组:若返回自定义分组类,优先调用分组类的
process()方法做批量处理、排序、过滤;若无自定义分组,则执行框架默认实现 -
结合
@ConditionalOnMissingBean等条件注解:容器中已存在用户自定义Bean,则跳过默认自动配置;不存在则加载框架默认配置,完美实现用户配置优先,框架配置兜底
四、条件过滤:@Conditional 系列注解
自动装配不会无脑加载所有配置类,而是通过条件注解判断环境,按需加载:
| 注解 | 作用 |
|---|---|
@ConditionalOnClass |
类路径下存在指定类时生效 |
@ConditionalOnMissingClass |
类路径下不存在指定类时生效 |
@ConditionalOnBean |
容器中存在指定 Bean 时生效 |
@ConditionalOnMissingBean |
容器中不存在指定 Bean 时生效 |
@ConditionalOnProperty |
配置文件存在指定属性时生效 |
示例:RedisAutoConfiguration 源码
@AutoConfiguration
@ConditionalOnClass(RedisOperations.class) // 类路径有Redis客户端才生效
@EnableConfigurationProperties(RedisProperties.class) // 绑定配置文件
@Import({ LettuceConnectionConfiguration.class, JedisConnectionConfiguration.class })
public class RedisAutoConfiguration {
@Bean
@ConditionalOnMissingBean(name = "redisTemplate") // 用户没自定义RedisTemplate时才创建
public RedisTemplate<Object, Object> redisTemplate(RedisConnectionFactory redisConnectionFactory) {
RedisTemplate<Object, Object> template = new RedisTemplate<>();
template.setConnectionFactory(redisConnectionFactory);
return template;
}
}
列如Spring中默认使用Cglib作为动态代理的原因:
使用了@ConditionalOnProperty 并且matchIfMissing为true
代码如下:

五、自动装配完整流程
- 启动类添加
@SpringBootApplication→ 触发@EnableAutoConfiguration @EnableAutoConfiguration通过@Import导入AutoConfigurationImportSelectorAutoConfigurationImportSelector调用selectImports- 从
META-INF/spring/...AutoConfiguration.imports读取所有自动配置类全类名 - 去重、处理
exclude排除、通过@Conditional条件过滤 - 将符合条件的配置类注入 Spring 容器
- 配置类中定义的
@Bean被实例化,完成自动装配
大致流程图:

六、引伸出自定义Starter
自定义 Spring Boot Starter 完整实现流程
基于前面所有自动装配、延迟导入、条件注解原理,自定义 Starter 是自动装配最核心的落地实战。其本质就是:手写一套独立的自动配置类 + 配置绑定 + 自动装配注册文件,实现第三方组件的开箱即用。
6.1 自定义 Starter 核心设计思想
遵循 Spring Boot 官方规范:自动配置兜底,用户配置优先,依托 DeferredImportSelector 延迟执行特性 + @Conditional 条件注解,实现无配置自动生效、有用户配置则覆盖的效果。
6.2 自定义 Starter 标准双模块结构(官方规范)
-
xxx-spring-boot-autoconfigure(自动配置模块):存放自动配置类、属性绑定类、核心业务逻辑,是 Starter 的核心
-
xxx-spring-boot-starter(启动器依赖模块):仅做依赖聚合,空工程,专门用于给业务项目引入依赖
6.3 完整开发流程
步骤1:编写配置属性绑定类(Properties)
用于绑定 application.yml/application.properties 自定义配置,实现配置可配置、可自定义。
核心注解:@ConfigurationProperties(prefix = "自定义前缀")
步骤2:编写核心业务功能 Service
封装 Starter 的核心业务逻辑,提供对外调用的方法,供项目使用。
步骤3:编写自动配置类(AutoConfiguration)
Starter 的核心,对应 Spring 官方的 RedisAutoConfiguration、WebAutoConfiguration。
核心注解组合:
-
@AutoConfiguration:标识为自动配置类 -
@ConditionalOnClass:项目存在指定核心类时才生效 -
@EnableConfigurationProperties:绑定配置属性类 -
@ConditionalOnMissingBean:用户未自定义Bean时,才自动注册默认Bean(核心:用户配置优先)
步骤4:注册自动配置入口(核心)
在资源目录创建文件:resources/META-INF/spring.factories/org.springframework.boot.autoconfigure.EnableAutoConfiguration
文件中写入自定义自动配置类的全类名,Spring Boot 启动时会通过 ImportCandidates 扫描加载该配置类,完成自动装配。
步骤5:聚合依赖、打包引用
在 starter 模块引入 autoconfigure 模块依赖,执行 Maven/Gradle 打包,业务项目直接引入 starter 依赖即可开箱即用,无需任何手动配置。
6.4 自定义 Starter 核心执行原理(串联前文知识点)
1. 业务项目引入 Starter 依赖 → 项目加载到自定义 autoconfigure 模块
2. 启动时 AutoConfigurationImportSelector 扫描所有 imports 文件,加载我们的自定义自动配置类
3. 依托 DeferredImportSelector 延迟执行特性:优先加载用户自定义 @Bean / @Configuration
4. 执行自动配置类逻辑,通过 @ConditionalOnMissingBean 判断:用户有Bean则不加载,用户无Bean则自动注册默认BeanDefinition
5. 由 BeanFactory 完成实例化,存入单例池,完成自定义组件自动装配
6.5 核心总结
自定义 Starter 本质:手写自动配置类 + 配置绑定 + 注册自动配置入口,依托延迟导入+条件注解,实现「零配置开箱即用,用户配置优先覆盖」。
更多推荐


所有评论(0)