天天看點

SpringBoot自動配置原理詳解

SpringBoot自動配置原理:

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

SpringBoot自動配置原理詳解

@EnableAutoConfiguration的作用是利用AutoConfigurationImportSelector給容器中導入一些元件。

SpringBoot自動配置原理詳解

可以檢視public String[] selectImports(AnnotationMetadata annotationMetadata)方法的内容。

SpringBoot自動配置原理詳解

通過protected List<String> getCandidateConfigurations(AnnotationMetadata metadata,      AnnotationAttributes attributes)擷取候選的配置,這個是掃描所有jar包類路徑下"META-INF/spring.factories";

SpringBoot自動配置原理詳解

然後把掃描到的這些檔案包裝成Properties對象。

SpringBoot自動配置原理詳解

從properties中擷取到EnableAutoConfiguration.class類名對應的值,然後把他們添加在容器中。

SpringBoot自動配置原理詳解

整個過程就是将類路徑下"META-INF/spring.factories"裡面配置的所有EnableAutoConfiguration的值加入到容器中。

SpringBoot自動配置原理詳解

每一個這樣XXAutoConfiguration類都是容器中的一個元件都加入到容器中,用他們來做自動配置。

每一個自動配置類進行自動配置功能,以HttpEncodingAutoConfiguration為例解釋自動配置原理。

SpringBoot自動配置原理詳解

根據目前不同的條件判斷,決定這個配置是否生效。

SpringBoot自動配置原理詳解

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>​

SpringBoot自動配置原理詳解

我們可以點選進去​<code>​@SpringBootApplication​</code>​注解中看看,可以發現有三個注解是比較重要的:

SpringBoot自動配置原理詳解

​<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

我們點進去看一下,發現有兩個比較重要的注解:

SpringBoot自動配置原理詳解

​<code>​@AutoConfigurationPackage​</code>​:自動配置包

​<code>​@Import​</code>​:給IOC容器導入元件

網上将這個​<code>​@AutoConfigurationPackage​</code>​注解解釋成自動配置包,我們也看看​<code>​@AutoConfigurationPackage​</code>​裡邊有什麼:

SpringBoot自動配置原理詳解

我們可以發現,依靠的還是​<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>​看看具體的實作是什麼:

SpringBoot自動配置原理詳解

我們再進去看一下這些配置資訊是從哪裡來的(進去getCandidateConfigurations方法):

SpringBoot自動配置原理詳解

這裡包裝了一層,我們看到的隻是通過SpringFactoriesLoader來加載,還沒看到關鍵資訊,繼續進去:

SpringBoot自動配置原理詳解

簡單梳理:

​<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>​的資料,然後添加到容器裡邊。

SpringBoot自動配置原理詳解

最後我們會預設加載113個預設的配置類:

SpringBoot自動配置原理詳解

有興趣的同學可以去翻一下這些檔案以及配置類哦:

SpringBoot自動配置原理詳解

​<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容器中,實作自動配置功能!

SpringBoot自動配置原理詳解

官網文檔參考:

​​https://docs.spring.io/spring-boot/docs/2.2.0.BUILD-SNAPSHOT/reference/html/using-spring-boot.html#using-boot-structuring-your-code​​