SpringBoot自動配置原理:
SpringBoot啟動的時候加載主配置類,開啟了自動配置功能@EnableAutoConfiguration。

@EnableAutoConfiguration的作用是利用AutoConfigurationImportSelector給容器中導入一些元件。
可以檢視public String[] selectImports(AnnotationMetadata annotationMetadata)方法的内容。
通過protected List<String> getCandidateConfigurations(AnnotationMetadata metadata, AnnotationAttributes attributes)擷取候選的配置,這個是掃描所有jar包類路徑下"META-INF/spring.factories";
然後把掃描到的這些檔案包裝成Properties對象。
從properties中擷取到EnableAutoConfiguration.class類名對應的值,然後把他們添加在容器中。
整個過程就是将類路徑下"META-INF/spring.factories"裡面配置的所有EnableAutoConfiguration的值加入到容器中。
每一個這樣XXAutoConfiguration類都是容器中的一個元件都加入到容器中,用他們來做自動配置。
每一個自動配置類進行自動配置功能,以HttpEncodingAutoConfiguration為例解釋自動配置原理。
根據目前不同的條件判斷,決定這個配置是否生效。
END
======================================================================================================================================================
2.轉自:https://zhuanlan.zhihu.com/p/55637237
SpringBoot自動配置原理
隻有光頭才能變強。 文本已收錄至我的GitHub倉庫,歡迎Star:https://github.com/ZhongFuCheng3y/3y
回顧前面Spring的文章(以學習的順序排好):
Spring入門這一篇就夠了
Spring【依賴注入】就是這麼簡單
Spring【AOP子產品】就這麼簡單
Spring【DAO子產品】知識要點
SpringMVC入門就這麼簡單
SpringMVC【開發Controller】詳解
SpringMVC【參數綁定、資料回顯、檔案上傳】
SpringMVC【校驗器、統一處理異常、RESTful、攔截器】
SpringBoot就是這麼簡單
SpringData JPA就是這麼簡單
Spring IOC知識點一網打盡!
Spring AOP就是這麼簡單啦
外行人都能看懂的SpringCloud,錯過了血虧!
作為一名Java程式員,就不可能不了解SpringBoot,如果不了解(趕緊學!)
不知道大家第一次搭SpringBoot環境的時候,有沒有覺得非常簡單。無須各種的配置檔案,無須各種繁雜的pom坐标,一個main方法,就能run起來了。與其他架構整合也賊友善,使用<code>EnableXXXXX</code>注解就可以搞起來了!
是以今天來講講SpringBoot是如何實作自動配置的~
我們可以發現,在使用<code>main()</code>啟動SpringBoot的時候,隻有一個注解<code>@SpringBootApplication</code>
我們可以點選進去<code>@SpringBootApplication</code>注解中看看,可以發現有三個注解是比較重要的:
<code>@SpringBootConfiguration</code>:我們點進去以後可以發現底層是Configuration注解,說白了就是支援JavaConfig的方式來進行配置(使用Configuration配置類等同于XML檔案)。
<code>@EnableAutoConfiguration</code>:開啟自動配置功能(後文詳解)
<code>@ComponentScan</code>:這個注解,學過Spring的同學應該對它不會陌生,就是掃描注解,預設是掃描目前類下的package。将<code>@Controller/@Service/@Component/@Repository</code>等注解加載到IOC容器中。
是以,<code>Java3yApplication</code>類可以被我們當做是這樣的:
我們知道SpringBoot可以幫我們減少很多的配置,也肯定聽過“約定大于配置”這麼一句話,那SpringBoot是怎麼做的呢?其實靠的就是<code>@EnableAutoConfiguration</code>注解。
簡單來說,這個注解可以幫助我們自動載入應用程式所需要的所有預設配置。
介紹有一句說:
if you have tomcat-embedded.jar on your classpath you are likely to want a TomcatServletWebServerFactory
如果你的類路徑下有<code>tomcat-embedded.jar</code>包,那麼你很可能就需要TomcatServletWebServerFactory
我們點進去看一下,發現有兩個比較重要的注解:
<code>@AutoConfigurationPackage</code>:自動配置包
<code>@Import</code>:給IOC容器導入元件
網上将這個<code>@AutoConfigurationPackage</code>注解解釋成自動配置包,我們也看看<code>@AutoConfigurationPackage</code>裡邊有什麼:
我們可以發現,依靠的還是<code>@Import</code>注解,再點進去檢視,我們發現重要的就是以下的代碼:
在預設的情況下就是将:主配置類(<code>@SpringBootApplication</code>)的所在包及其子包裡邊的元件掃描到Spring容器中。
看完這句話,會不會覺得,這不就是ComponentScan的功能嗎?這倆不就重複了嗎?
我開始也有這個疑問,直到我看到文檔的這句話:
it will be used when scanning for code @Entity classes. It is generally recommended that you place EnableAutoConfiguration (if you're not using @SpringBootApplication) in a root package so that all sub-packages and classes can be searched.
比如說,你用了Spring Data JPA,可能會在實體類上寫<code>@Entity</code>注解。這個<code>@Entity</code>注解由<code>@AutoConfigurationPackage</code>掃描并加載,而我們平時開發用的<code>@Controller/@Service/@Component/@Repository</code>這些注解是由<code>ComponentScan</code>來掃描并加載的。
簡單了解:這二者掃描的對象是不一樣的。
我們回到<code>@Import(AutoConfigurationImportSelector.class)</code>這句代碼上,再點進去<code>AutoConfigurationImportSelector.class</code>看看具體的實作是什麼:
我們再進去看一下這些配置資訊是從哪裡來的(進去getCandidateConfigurations方法):
這裡包裝了一層,我們看到的隻是通過SpringFactoriesLoader來加載,還沒看到關鍵資訊,繼續進去:
簡單梳理:
<code>FACTORIES_RESOURCE_LOCATION</code>的值是<code>META-INF/spring.factories</code>
Spring啟動的時候會掃描所有jar路徑下的<code>META-INF/spring.factories</code>,将其檔案包裝成Properties對象
從Properties對象擷取到key值為<code>EnableAutoConfiguration</code>的資料,然後添加到容器裡邊。
最後我們會預設加載113個預設的配置類:
有興趣的同學可以去翻一下這些檔案以及配置類哦:
<code>@SpringBootApplication</code>等同于下面三個注解:
<code>@SpringBootConfiguration</code>
<code>@EnableAutoConfiguration</code>
<code>@ComponentScan</code>
其中<code>@EnableAutoConfiguration</code>是關鍵(啟用自動配置),内部實際上就去加載<code>META-INF/spring.factories</code>檔案的資訊,然後篩選出以<code>EnableAutoConfiguration</code>為key的資料,加載到IOC容器中,實作自動配置功能!
官網文檔參考:
https://docs.spring.io/spring-boot/docs/2.2.0.BUILD-SNAPSHOT/reference/html/using-spring-boot.html#using-boot-structuring-your-code