SpringFramework源码解析——Spring Boot是如何实现自动配置的?
本文基于Spring Boot 2.7.0,Spring Framework 5.3.20 编写。
1. 背景
1.1. 什么是自动配置?
当我们需要集成某些功能时,只需要依赖Spring Boot或第三方提供的Starter即可,自动配置机制会将相关的配置注册到容器中,开箱即用,降低了开发人员的使用成本。通过@EnableAutoConfiguration
注解可以开启自动配置。
以Spring Boot应用集成Redis为例,首先在pom文件中依赖spring-boot-starter-data-redis
,然后在配置文件中配置Redis相关配置,便可使用依赖注入RedisTemplate
来操作Redis。
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-data-redis</artifactId>
</dependency>
1.2. 什么是条件配置?
条件配置是指在配置上标注条件注解,以根据特定的条件来启用或禁用该配置。常见的条件注解有@ConditionalOnClass
,@ConditionalOnMissingBean
,ConditionalOnProperty
等。
条件注解的原理见文章:@Configuration及其周边注解是如何生效的?
1.3. Spring Boot和Spring有什么区别?
Spring Boot对Spring进行了封装,提供了内置容器,自动配置等功能,简化了开发流程,开箱即用。
2. 自动配置是如何实现的?
当我们通过@EnableAutoConfiguration
注解开启自动配置时,其标注的@Import
注解导入了AutoConfigurationImportSelector
。
在配置类后置处理器ConfigurationClassPostProcessor
处理的过程中,会调用AutoConfigurationImportSelector#getAutoConfigurationEntry
获取自动配置,最后完成自动配置的注册。下面我们重点来看自动配置的获取。
@Import
注解的原理见文章:@Configuration及其周边注解是如何生效的?
2.1. 获取候选的自动配置
- 从
META-INF/spring.factories
文件中获取org.springframework.boot.autoconfigure.EnableAutoConfiguration
指定的自动配置;该方式已在后续的版本中移除; - 从
META-INF/spring/org.springframework.boot.autoconfigure.AutoConfiguration.imports
文件中获取自动配置; - 返回候选的自动配置。
对应源码所在位置:
AutoConfigurationImportSelector#getCandidateConfigurations
。SpringFactoriesLoader#loadFactoryNames
。ImportCandidates#load
。
2.2. 移除重复的自动配置
对候选的自动配置进行去重。
对应源码所在位置:
AutoConfigurationImportSelector#removeDuplicates
。
2.3. 移除排除的自动配置
- 获取
@EnableAutoConfiguration
注解中exclude
属性排除的自动配置; - 获取
@EnableAutoConfiguration
注解中excludeName
属性排除的自动配置; - 获取配置文件中
spring.autoconfigure.exclude
排除的自动配置; - 从候选的自动配置中移除上面排除的自动配置。
对应源码所在位置:
AutoConfigurationImportSelector#getExclusions
。
2.4. 过滤自动配置
- 从
META-INF/spring.factories
文件中获取org.springframework.boot.autoconfigure.AutoConfigurationImportFilter
配置的自动配置导入过滤器; - 委派给自动配置导入过滤器对候选的自动配置进行过滤。
对应源码所在位置:
AutoConfigurationImportSelector.ConfigurationClassFilter#filter
。
2.5. 发布自动配置导入事件
- 从
META-INF/spring.factories
文件中获取org.springframework.boot.autoconfigure.AutoConfigurationImportListener
配置的自动配置导入监听器; - 委派给自动配置导入监听器接收自动配置导入事件。
对应源码所在位置:
AutoConfigurationImportSelector#fireAutoConfigurationImportEvents
。