前言
只有光頭才能變強。
文本已收錄至我的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的自動配置原理
不知道大家第一次搭SpringBoot環境的時候,有沒有覺得非常簡單。無須各種的配置文件,無須各種繁雜的pom坐標,一個main方法,就能run起來了。與其他框架整合也賊方便,使用EnableXXXXX注解就可以搞起來了!
所以今天來講講SpringBoot是如何實現自動配置的~
1.1三個重要的注解
我們可以發現,在使用main()啟動SpringBoot的時候,只有一個注解@SpringBootApplication

我們可以點擊進去@SpringBootApplication注解中看看,可以發現有三個注解是比較重要的:

@SpringBootConfiguration:我們點進去以后可以發現底層是Configuration注解,說白了就是支持JavaConfig的方式來進行配置(使用Configuration配置類等同於XML文件)。@EnableAutoConfiguration:開啟自動配置功能(后文詳解)@ComponentScan:這個注解,學過Spring的同學應該對它不會陌生,就是掃描注解,默認是掃描當前類下的package。將@Controller/@Service/@Component/@Repository等注解加載到IOC容器中。
所以,Java3yApplication類可以被我們當做是這樣的:
@SpringBootConfiguration
@EnableAutoConfiguration
@ComponentScan
public class Java3yApplication {
public static void main(String[] args) {
SpringApplication.run(Java3yApplication.class, args);
}
}
1.2重點EnableAutoConfiguration
我們知道SpringBoot可以幫我們減少很多的配置,也肯定聽過“約定大於配置”這么一句話,那SpringBoot是怎么做的呢?其實靠的就是@EnableAutoConfiguration注解。
簡單來說,這個注解可以幫助我們自動載入應用程序所需要的所有默認配置。
介紹有一句說:
if you have tomcat-embedded.jar on your classpath you are likely to want a TomcatServletWebServerFactory
如果你的類路徑下有tomcat-embedded.jar包,那么你很可能就需要TomcatServletWebServerFactory
我們點進去看一下,發現有兩個比較重要的注解:

@AutoConfigurationPackage:自動配置包@Import:給IOC容器導入組件
1.2.1AutoConfigurationPackage
網上將這個@AutoConfigurationPackage注解解釋成自動配置包,我們也看看@AutoConfigurationPackage里邊有什么:

我們可以發現,依靠的還是@Import注解,再點進去查看,我們發現重要的就是以下的代碼:
@Override
public void registerBeanDefinitions(AnnotationMetadata metadata,
BeanDefinitionRegistry registry) {
register(registry, new PackageImport(metadata).getPackageName());
}
在默認的情況下就是將:主配置類(@SpringBootApplication)的所在包及其子包里邊的組件掃描到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,可能會在實體類上寫@Entity注解。這個@Entity注解由@AutoConfigurationPackage掃描並加載,而我們平時開發用的@Controller/@Service/@Component/@Repository這些注解是由ComponentScan來掃描並加載的。
- 簡單理解:這二者掃描的對象是不一樣的。
1.2.2回到Import
我們回到@Import(AutoConfigurationImportSelector.class)這句代碼上,再點進去AutoConfigurationImportSelector.class看看具體的實現是什么:

我們再進去看一下這些配置信息是從哪里來的(進去getCandidateConfigurations方法):

這里包裝了一層,我們看到的只是通過SpringFactoriesLoader來加載,還沒看到關鍵信息,繼續進去:

簡單梳理:
FACTORIES_RESOURCE_LOCATION的值是META-INF/spring.factories- Spring啟動的時候會掃描所有jar路徑下的
META-INF/spring.factories,將其文件包裝成Properties對象 - 從Properties對象獲取到key值為
EnableAutoConfiguration的數據,然后添加到容器里邊。

最后我們會默認加載113個默認的配置類:

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

1.3總結
@SpringBootApplication等同於下面三個注解:
@SpringBootConfiguration@EnableAutoConfiguration@ComponentScan
其中@EnableAutoConfiguration是關鍵(啟用自動配置),內部實際上就去加載META-INF/spring.factories文件的信息,然后篩選出以EnableAutoConfiguration為key的數據,加載到IOC容器中,實現自動配置功能!

官網文檔參考:
英語不好的同學可以像我一樣,對照着來看:

最后
樂於輸出干貨的Java技術公眾號:Java3y。公眾號內有200多篇原創技術文章、海量視頻資源、精美腦圖,不妨來關注一下!

覺得我的文章寫得不錯,不妨點一下贊!
