SpringBoot自動裝配原理及配置流程
SpringBoot的自動裝配是其核心特性之一,他簡化了Spring應(yīng)用的配置流程,實(shí)現(xiàn)了“約定大于配置”的理念。其核心原理可以概括為:通過特定的注解和配置文件,自動識別并加載符合條件的Bean到Spring容器中。
1.核心注解:@SpringBootApplication

自動裝配的入口是主類上的@SpringBootApplication注解,它是一個符合注解,包含三個關(guān)鍵注解:
- @SpringBootConfiguration:標(biāo)記當(dāng)前類為配置類(本質(zhì)上是@Configuration的派生注解)
- @ComponentScan:掃描當(dāng)前包及其子包下的@Component,@Service等注解的類,注冊為Bean。
- @EnableAutoConfiguration:開啟自動配置的核心注解,也是自動裝配的關(guān)鍵。
2.@EnableAutoConfiguration的作用
當(dāng)我們點(diǎn)進(jìn)去這個核心注解的時候:

EnableAutoConfiguration注解實(shí)現(xiàn)自動裝配機(jī)制的時候,主要依賴于這個@Import({AutoConfigurationImportSelector.class}),通過import的導(dǎo)入到AutoConfigurationImportSelector類,該類負(fù)責(zé)篩選并導(dǎo)入需要自動裝配的類。其中這個類的話實(shí)現(xiàn)自動裝配依賴于selectImports()這個方法。

這個方法通過在內(nèi)部調(diào)用getAutoConfigurationEntry方法來實(shí)現(xiàn)自動裝配。

getCandidateConfigurations()這個方法會告訴要想將沒有spingbootapplication注解啟動的類,但是想讓spring幫助我們進(jìn)行注冊Bean需要將類的全限定名加到某個文件中。
getCandidateConfigurations()這個方法具體實(shí)現(xiàn):
protected List<String> getCandidateConfigurations(AnnotationMetadata metadata, AnnotationAttributes attributes) {
List<String> configurations = ImportCandidates.load(AutoConfiguration.class, this.getBeanClassLoader()).getCandidates();
Assert.notEmpty(configurations, "No auto configuration classes found in META-INF/spring/org.springframework.boot.autoconfigure.AutoConfiguration.imports. If you are using a custom packaging, make sure that file is correct.");
return configurations;
}META-INF/spring/org.springframework.boot.autoconfigure.AutoConfiguration.imports
也就是將需要注冊的類全限定名寫入到這個文件中。
舉一個例子:
我們在另外一個工程里面封裝了redis的一些方法以及redis的相關(guān)配置。希望能夠在外部中引用RedisService這個對象。但是這個工程中并沒有springbootapplication啟動注解。所以將這個類的全限定名寫入到以上這個文件中。


有兩點(diǎn)需要進(jìn)行注意:
一是一般這個文件創(chuàng)建在resources這個目錄下,META-INF和spring這是兩個目錄,先創(chuàng)建META-INF目錄再創(chuàng)建spring目錄。同時在創(chuàng)建的時候需要打開一個東西。


把compact給取消掉。是因?yàn)樵诠催x上的話,創(chuàng)建的話不容易看出這是一個二級目錄,我們想要的效果就是達(dá)到以下圖片的效果。

3.詳細(xì)解讀getAutoConfigurationEntry()
if (!this.isEnabled(annotationMetadata)) {
return EMPTY_ENTRY;
}首先判斷自動配置功能是否開啟。
isEnabled()方法會檢查屬性@EnableAutofiguration注解的enabled屬性(默認(rèn)為true),也可能結(jié)合其他全局開關(guān)。如果返回false的,表示關(guān)閉自動配置,直接返回空結(jié)果。
AnnotationAttributes attributes = this.getAttributes(annotationMetadata);
從注解元數(shù)據(jù)AnnotationMetadata中提取@EnableAutoConfiguration的屬性信息。
@EnableAutoConfiguration有exclude,excludeName等屬性(用于指定需要排除的自動配置類),getAttributes()會將這些屬性解析為AnnotationAttribute對象,方便后續(xù)處理。
List<String> configurations = this.getCandidateConfigurations(annotationMetadata, attributes);
獲取所有候選自動配置類的全限定名
getCandidateConfigurations()方法會讀取類路徑下 META-INF/spring/org.springframework.boot.autoconfigure.AutoConfiguration.imports文件中,以org.springframework.boot.autoconfigure.EnableAutoConfiguration為key的所有值(這些值就是Spring Boot預(yù)定義的自動配置類,如WebMvcAutConfiguration等。
configurations = this.removeDuplicates(configurations);
對候選配置類去重,避免同一個配置類被多次加載。
如果多個 META-INF/spring/org.springframework.boot.autoconfigure.AutoConfiguration.imports文件定義了同一個自動配置類,這里確保最終只保留一個。
Set<String> exclusions = this.getExclusions(annotationMetadata, attributes);
收集所有需要排除的自動配置類
@EnableAutoConfiguration注解的exclude屬性(直接指定類)或者是excludeName屬性指定類名。還可以通過配置文件application.yaml中通過spring.autoconfigure.exclude配置的類。
this.checkExcludedClasses(configurations, exclusions);
檢查需要排除的類是否確實(shí)存在于候選配置類中。
如果用戶排除了一個不存在的自動配置類(如拼寫錯誤),這里會拋出異常(illegalArgumentException),提前暴露配置錯誤。
configurations.removeAll(exclusions);
將需要排除的類從候選配置類列表中徹底移除。
被排除的類不會被Spring容器加載,實(shí)現(xiàn)了“自定義排除不需要的自動配置”的功能。
configurations = this.getConfigurationClassFilter().filter(configurations);
通過條件過濾器篩選出符合當(dāng)前環(huán)境的配置類。
過濾器會檢查每個候選配置類上的@Conditional系類注解(如@ConditionalOnClass,@ConditionalOnMissingBean等),只有滿足所有條件的配置類才會被保留。
this.fireAutoConfigurationImportEvents(configurations, exclusions);
觸發(fā)自動配置導(dǎo)入事件,通知相關(guān)監(jiān)聽器(AutoConfigurationImportListenter)。
允許外部自動配置進(jìn)行擴(kuò)展(如日志記錄,額外處理等)。
return new AutoConfigurationEntry(configurations, exclusions);
將篩選后的有效配置類和排除類封裝為AutoConfigurationEntry對象并返回。
Spring 容器會根據(jù)該結(jié)果,將configurations中的類作為類加載,從而完成自動裝配。
總結(jié):
1.先檢查開關(guān),確保自動配置啟用
2.加載預(yù)定義的候選配置類
3.處理去重和排除,移除不需要的類
4.通過@Conditional注解篩選符合當(dāng)前環(huán)境的類
5.發(fā)布事件并返回結(jié)果
最終,篩選后的配置類會被Spring容器加載,其內(nèi)部定義的@Bean方法會生成相應(yīng)的Bean,實(shí)現(xiàn)自動配置的效果。
到此這篇關(guān)于SpringBoot自動裝配原理及配置流程的文章就介紹到這了,更多相關(guān)SpringBoot自動裝配內(nèi)容請搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持腳本之家!
相關(guān)文章
手把手教你寫Maven的archetype項(xiàng)目腳手架
本文主要介紹了Maven的archetype項(xiàng)目腳手架,文中通過示例代碼介紹的非常詳細(xì),具有一定的參考價值,感興趣的小伙伴們可以參考一下2021-08-08
Gradle下如何搭建SpringCloud分布式環(huán)境
這篇文章主要介紹了Gradle下如何搭建SpringCloud分布式環(huán)境問題,具有很好的參考價值,希望對大家有所幫助,如有錯誤或未考慮完全的地方,望不吝賜教2025-05-05
POI導(dǎo)出之Excel實(shí)現(xiàn)單元格的背景色填充問題
這篇文章主要介紹了POI導(dǎo)出之Excel實(shí)現(xiàn)單元格的背景色填充問題,具有很好的參考價值,希望對大家有所幫助。如有錯誤或未考慮完全的地方,望不吝賜教2023-03-03
Java實(shí)現(xiàn)批量修改txt文件名稱的方法示例
這篇文章主要介紹了Java實(shí)現(xiàn)批量修改txt文件名稱的方法,結(jié)合實(shí)例形式分析了Java針對目錄文件遍歷及文件讀寫、屬性操作等相關(guān)實(shí)現(xiàn)技巧,需要的朋友可以參考下2019-03-03
Spring中的spring.factories文件用法(Spring如何加載第三方Bean)
這篇文章主要介紹了Spring中的spring.factories文件用法(Spring如何加載第三方Bean),具有很好的參考價值,希望對大家有所幫助。如有錯誤或未考慮完全的地方,望不吝賜教2021-10-10
Java實(shí)現(xiàn)WORD和PDF互相轉(zhuǎn)換以及數(shù)據(jù)填充示例
本文介紹了如何使用Java實(shí)現(xiàn)WORD和PDF的互轉(zhuǎn)以及數(shù)據(jù)填充功能,通過導(dǎo)入Aspose庫并使用其工具類,可以輕松實(shí)現(xiàn)WORD和PDF模板的填充和轉(zhuǎn)換,需要的朋友可以參考下2025-02-02
JavaMail實(shí)現(xiàn)發(fā)送郵件功能
這篇文章主要為大家詳細(xì)介紹了JavaMail實(shí)現(xiàn)發(fā)送郵件功能,具有一定的參考價值,感興趣的小伙伴們可以參考一下2017-08-08

