SpringBoot學習筆記(三) SpringBoot 自動配置原理
SpringBoot自動配置
SpringBoot自動配置的註解是@EnableAutoConfiguration
所以來看@EnableAutoConfiguration註解的原始碼:
1、首先@EnableAutoConfiguration是包含在@SpringBootApplication組合註解中
2、使用@Import注入EnableAutoConfigurationImportSelector.class這個類
這裡講一下@Import註解:
@Import註解在4.2之前只支援匯入配置類
在4.2,@Import註解支援匯入普通的java類,並將其宣告成一個bean
所以在Spring4.2之後就可以使用@Import既可以匯入其他配置類,又可以匯入一個普通的java類,並將其宣告成一個bean。
所以我們重點來看一下EnableAutoConfigurationImportSelector.class
@Deprecated:從它的定義我們可以知道,它會被文件化,能夠保留到執行時,能夠修飾構造方法、屬性、區域性變數、方法、包、引數、型別。
程式碼解釋:
首先EnableAutoConfigurationImportSelector繼承了AutoConfigurationImportSelector類,並且重寫了isEnabled方法。
isEnabled():
比較當前類是不是EnableAutoConfigurationImportSelector類。
所以核心載入配置列表的功能是在AutoConfigurationImportSelector中:
而這個方法中getCandidateConfigurations()去載入配置列表
這裡和SpringBoot啟動原理時去載入listener等配置檔案時用相同的方式,通過SpringFactoriesLoader類的loadFactoryNames方法,去找當前META-INF/spring.factories檔案。
而自動配置相關包是spring-boot-autoconfigure.jar,所以相應的spring.factories檔案也在這個包下:
這裡只是一部分:
而在這些配置類中,隨便點開一個發現,這些配置類會根據當前的條件註解的限制,會在不同的條件下去建立對應的Bean。
而條件註解相應的包在org.springframework.boot.autoconfigure.condition下:
@ConditionalOnBean:當容器裡有指定的Bean的條件下
@ConditionalOnClass:當類路徑下有指定的類的條件下
@ConditionalOnException:基於SpEL表示式作為判斷條件
@ConditionalOnJava:在JNDI存在的條件下查詢指定的位置
@ConditionalOnMissingBean:當容器裡沒有指定Bean的情況下
@ConditionalOnMissingClass:當類路徑下沒有指定的類的條件下
@ConditionalOnNotWebApplication:當前專案不是web專案的條件下
@ConditionalOnProperty:指定的屬性是否有指定的值
@ConditionalOnResource:類路徑是否有指定的值
@ConditionalOnSingleCandidate:當指定Bean在容器中只有一個,或者雖然有多個但是指定首選的Bean
@ConditionalOnWebApplication:當前專案是Web專案的條件下
上面這些註解都是組合了@Conditional元註解,只是使用了不同的條件(Conditional)
例項(自定義starter pom 當某個類存在的時候,自動配置這個類的Bean,並可將Bean的屬性在application.properties中配置):
1、新增依賴:
這裡的spring-boot-configuration-processor是配置處理器,處理配置。
2、屬性配置:
這裡是型別安全的獲取。在application.properties中通過hello.msg =來設定,如果不設定,則預設為hello.msg=world.
3、判斷依據類
這裡是根據此類的存在與否來建立這個類的Bean,這個類可以是第三方類庫的類
4、自動配置類
根據HelloServiceProperties中提供的引數,並通過@ConditionalOnClass判斷HelloService這個類在類路徑中是否存在,且當容器中沒有這個Bean的情況下自動配置這個Bean。
5、註冊配置
如果想要自動配置生效,需要註冊自動配置類。在src/main/resources下新建META-INF/spring.factories,並填寫如圖所示的內容。
6、打包到本地
在idea內嵌maven外掛,使用maven install 命令,打包到本地
7、新建springboot專案,新增依賴
此時,如果檢視包結構,會發現,我們之前自定義的starter作為依賴被匯入,並且根據相關條件已經自動配置
好相應的Bean。
8、使用自動配置的Bean
通過@Autowired註解,注入之前自動配置好的Bean。就可以對Bean進行操作
9、通過在application.properties中設定debug = true檢視相應自動配置情況
此時,會發現,我們之前自定義的starter已經自動配置顯示在控制檯的報告中。