文章目錄
- 1. 自動化裝配的起點:`@SpringBootApplication`
- 2. 自動化裝配的核心機制:`@EnableAutoConfiguration` 和 `AutoConfigurationImportSelector`
- 3. 自動化配置的注冊方式:`spring.factories` 與 `.imports`
- 3.1 早期版本:`META-INF/spring.factories`
- 3.2 現代版本:`META-INF/spring/org.springframework.boot.autoconfigure.AutoConfiguration.imports`
- 4. 運行時類路徑:自動化配置的基礎
- 5. 條件判斷:決定配置是否生效
- 6. 總結
Spring Boot 自動化裝配是其最引人注目的特性之一,它極大地簡化了 Spring 應用的配置,讓開發者能夠更專注于業務邏輯本文將帶深入探討 Spring Boot 自動化裝配的原理,并回顧其從早期版本到現代版本的演進過程
1. 自動化裝配的起點:@SpringBootApplication
每個 Spring Boot 應用的入口點通常都有一個 @SpringBootApplication
注解這個復合注解是自動化裝配的起點,它集成了三個核心注解:
@SpringBootConfiguration
: 標記當前類為配置類,等同于@Configuration
@EnableAutoConfiguration
: 開啟 Spring Boot 自動化裝配的關鍵注解@ComponentScan
: 開啟組件掃描,用于發現和注冊應用內的 Bean
其中,@EnableAutoConfiguration
是自動化裝配的核心
2. 自動化裝配的核心機制:@EnableAutoConfiguration
和 AutoConfigurationImportSelector
@EnableAutoConfiguration
注解內部通過 @Import
注解導入了一個名為 AutoConfigurationImportSelector
的類
@Target({ElementType.TYPE})
@Retention(RetentionPolicy.RUNTIME)
@Documented
@Inherited
@AutoConfigurationPackage
@Import({AutoConfigurationImportSelector.class}) // 核心在這里!
public @interface EnableAutoConfiguration {// ...
}
AutoConfigurationImportSelector
的主要職責是在應用啟動時,找到并加載所有符合條件的自動化配置類
3. 自動化配置的注冊方式:spring.factories
與 .imports
Spring Boot 自動化配置類并不是隨便放在項目中的,它們需要被“注冊”起來,以便 AutoConfigurationImportSelector
能夠發現它們在 Spring Boot 的不同版本中,注冊方式有所演進
3.1 早期版本:META-INF/spring.factories
在 Spring Boot 2.7 版本之前,自動化配置類主要通過 META-INF/spring.factories
文件進行注冊這個文件位于 JAR 包的 META-INF
目錄下,遵循 Java 的 Service Provider Interface (SPI) 機制
spring.factories
是一個屬性文件,其中 org.springframework.boot.autoconfigure.EnableAutoConfiguration
鍵對應的值就是自動化配置類的全限定名列表,用逗號分隔
# 示例:早期版本 Starter 中的 META-INF/spring.factories
org.springframework.boot.autoconfigure.EnableAutoConfiguration=\
org.springframework.boot.autoconfigure.jdbc.DataSourceAutoConfiguration,\
org.springframework.boot.autoconfigure.web.servlet.WebMvcAutoConfiguration
AutoConfigurationImportSelector
在早期版本中主要依賴 SpringFactoriesLoader
工具類來讀取這些 spring.factories
文件SpringFactoriesLoader
會掃描當前應用的整個運行時類路徑,查找所有 JAR 包中的 META-INF/spring.factories
文件,并加載指定鍵對應的值
3.2 現代版本:META-INF/spring/org.springframework.boot.autoconfigure.AutoConfiguration.imports
從 Spring Boot 2.7 版本開始,為了使自動化配置的注冊更加清晰和規范,引入了 META-INF/spring/org.springframework.boot.autoconfigure.AutoConfiguration.imports
這個專門用于注冊自動化配置類的文件
這個文件每行包含一個自動化配置類的全限定名
# 示例:現代版本 Starter 中的 META-INF/spring/org.springframework.boot.autoconfigure.AutoConfiguration.imports
org.springframework.boot.autoconfigure.jdbc.DataSourceAutoConfiguration
org.springframework.boot.autoconfigure.web.servlet.WebMvcAutoConfiguration
在 Spring Boot 2.7+ 版本中,AutoConfigurationImportSelector
會同時從 spring.factories
和 .imports
文件中加載自動化配置類如我們之前分析的 getCandidateConfigurations
方法所示:
protected List<String> getCandidateConfigurations(AnnotationMetadata metadata, AnnotationAttributes attributes) {// 從 spring.factories 加載List<String> configurations = new ArrayList(SpringFactoriesLoader.loadFactoryNames(this.getSpringFactoriesLoaderFactoryClass(), this.getBeanClassLoader()));// 從 .imports 文件加載 (Spring Boot 2.7+ 新增)ImportCandidates.load(AutoConfiguration.class, this.getBeanClassLoader()).forEach(configurations::add);// ... 檢查是否找到配置類return configurations;
}
在 Spring Boot 3.x 版本中,.imports
文件成為了主要和推薦的自動化配置注冊方式
4. 運行時類路徑:自動化配置的基礎
無論是 spring.factories
還是 .imports
文件,AutoConfigurationImportSelector
能夠找到它們的前提是它們所在的 JAR 包存在于應用的 運行時類路徑 (Runtime Classpath) 中
運行時類路徑是 JVM 在運行的 Java 應用程序時,用來查找和加載 .class
文件的路徑集合它包括:
- 自己的項目編譯輸出的
.class
文件- 項目依賴的所有 JAR 包
- JDK 自帶的類庫
SpringFactoriesLoader
和 ImportCandidates
工具類正是利用了 JVM 的類加載機制,遍歷整個運行時類路徑,查找指定位置的資源文件當通過 Maven 或 Gradle 引入一個 Spring Boot Starter 或其他包含自動化配置的 JAR 包時,這個 JAR 包就會被添加到的運行時類路徑中,從而使得其中的 spring.factories
或 .imports
文件能夠被 Spring Boot 發現
5. 條件判斷:決定配置是否生效
找到自動化配置類只是第一步Spring Boot 的自動化裝配之所以智能,是因為它會根據當前應用程序的環境來決定哪些配置類應該真正生效這個決策過程依賴于一系列的條件注解
這些條件注解通常加在自動化配置類或其中的 @Bean
方法上常見的條件注解包括:
@ConditionalOnClass
: 當指定的類存在于運行時類路徑中時生效@ConditionalOnMissingBean
: 當 Spring 容器中不存在指定類型的 Bean 時生效@ConditionalOnProperty
: 當指定的配置屬性存在且符合指定值時生效@ConditionalOnResource
: 當指定的資源文件存在于類路徑中時生效@ConditionalOnWebApplication
: 當應用程序是 Web 應用時生效- 等等…
AutoConfigurationImportSelector
在加載了候選的自動化配置類名后,會進一步檢查這些類上的條件注解只有當所有條件注解都滿足時,這個自動化配置類才會被激活,其中的 Bean 定義才會被注冊到 Spring 容器中
舉例來說:
如果引入了
spring-boot-starter-data-redis
依賴,那么 Redis 相關的 JAR 包會出現在的運行時類路徑中,其中包含RedisOperations.class
等類spring-boot-autoconfigure
模塊中的RedisAutoConfiguration
類上帶有@ConditionalOnClass({ RedisOperations.class, RedisConnectionFactory.class })
注解因為這些類存在,條件滿足,RedisAutoConfiguration
生效,Spring Boot 自動為配置 Redis 相關的 Bean
如果沒有引入該依賴,這些類不存在,條件不滿足,RedisAutoConfiguration
被忽略
6. 總結
Spring Boot 自動化裝配是一個強大而智能的特性,它通過以下機制實現:
@EnableAutoConfiguration
: 開啟自動化裝配AutoConfigurationImportSelector
: 核心選擇器,負責查找和加載自動化配置類- 注冊文件 (
spring.factories
和.imports
): 聲明哪些類是自動化配置類,位于 JAR 包的特定位置 - 運行時類路徑: 這些注冊文件必須存在于應用的運行時類路徑中才能被發現
- 條件注解 (
@ConditionalOnClass
等): 根據當前環境決定自動化配置是否生效