Spring Boot — 自動配置原理
- 2020 年 2 月 10 日
- 筆記
啟用自動配置
在Spring Boot中自動配置一般使用@EnableXXX
方式,Spring默認提供了@EnableAutoConfiguration
來配置starter,另外還提供了類似@EnableScheduling
來配置非starter的相關bean,從源碼角度來看,兩種方式本質上來說並沒什麼區別,其都使用了@Import
來導入一個對應的配置入口類,然後正在啟動中的Spring IoC容器會嘗試初始化該類,那麼該配置入口類相當於拿到了ApplicationContext
,自然可以做很多的自由發揮。
清單1:EnableAutoConfiguration源碼
@Target(ElementType.TYPE) @Retention(RetentionPolicy.RUNTIME) @Documented @Inherited @AutoConfigurationPackage @Import(EnableAutoConfigurationImportSelector.class) public @interface EnableAutoConfiguration { String ENABLED_OVERRIDE_PROPERTY = "spring.boot.enableautoconfiguration"; // ....... }
清單2:EnableScheduling源碼
@Target(ElementType.TYPE) @Retention(RetentionPolicy.RUNTIME) @Import(SchedulingConfiguration.class) @Documented public @interface EnableScheduling { }
如何自動配置
所謂的自動配置就是執行具體的Configuration
類,首先先看比較簡單的@EnableScheduling
註解,該註解對應的配置類為SchedulingConfiguration
,在SchedulingConfiguration
中往IOC中注入了一個DestructionAwareBeanPostProcessor
處理器,用於掃描定時器方法,然後初始化整個定時器調度。 這個簡單的自動配置也說明了@EnableXXX
本質上是一個開關,告訴Spring該去配置哪些東西,該怎麼配置這些東西。 清單3:EnableScheduling對應的SchedulingConfiguration配置
@Configuration @Role(BeanDefinition.ROLE_INFRASTRUCTURE) public class SchedulingConfiguration { @Bean(name = TaskManagementConfigUtils.SCHEDULED_ANNOTATION_PROCESSOR_BEAN_NAME) @Role(BeanDefinition.ROLE_INFRASTRUCTURE) public ScheduledAnnotationBeanPostProcessor scheduledAnnotationProcessor() { return new ScheduledAnnotationBeanPostProcessor(); } }
那麼對於starter模組是如何做到自動配置的呢?答案是@EnableAutoConfiguration
,該註解對應的配置類為EnableAutoConfigurationImportSelector
,該類實現了ImportSelector
介面,在Spring Boot的Application Context啟動時會主動調用其org.springframework.context.annotation.ImportSelector#selectImports
方法,那麼自動注入的核心就在該方法中。
在EnableAutoConfigurationImportSelector
在啟動後回去掃描META-INF/spring.factories
文件,該文件是Spring Boot提供的Starter自我配置的入口,以mybatis starter為例,其形式如下: 清單4: mybatis starter配置
# Auto Configure org.springframework.boot.autoconfigure.EnableAutoConfiguration= org.mybatis.spring.boot.autoconfigure.MybatisAutoConfiguration
其目地告訴Spring Boot使用org.mybatis.spring.boot.autoconfigure.MybatisAutoConfiguration
來配置我這個模組,Spring Boot獲取到該配置後會經過一系列的判斷(比如是否被用戶手動exclude),然後決定載入後將該類納入Spring Boot的配置中去,讓IoC容器去完成配置。到此整個自動配置發現流程就算完成,這種方式類似Java提供的SPI,利用classpath下的配置資訊達到批量自動配置的目地。
如何利用自動配置
自動配置的原理是很簡單的,總結起來就兩種,如果你想要讓用戶主動配置,那麼可以提供一個自定義的EnableXXX
註解,在該註解中import對應的配置類,如果你想讓Spring Boot再啟動的時候自動配置,那麼在META-INF
下提供對應的spring.factories文件,讓Spring自動載入對應的配置類。
Spring Boot利用這種做法能讓模組與模組之間解耦,所有的模組之間通過IoC容器進行聯繫,那麼對寫程式碼就很有啟發了,比如在項目中要對接多個簡訊服務商,那麼每一個簡訊服務商實際上就是一個Plugin,那麼給每一個服務商寫一個EnableXXX
註解,讓Spring自動配置到IoC容器中,使用方也只需要從IoC中獲取,也是一種不錯的解耦的設計。
參考
Creating Your Own Auto-configuration
- 版權聲明: 感謝您的閱讀,本文由屈定's Blog版權所有。如若轉載,請註明出處。
- 文章標題: Spring Boot — 自動配置原理
- 文章鏈接: https://mrdear.cn/2019/01/19/framework/spring/spring-boot–autoconfig/