SpringBoot自動配置原理

前言

只有光頭才能變強。html

文本已收錄至個人GitHub倉庫,歡迎Star:github.com/ZhongFuChen…java

回顧前面Spring的文章(以學習的順序排好):git

做爲一名Java程序員,就不可能不瞭解SpringBoot,若是不瞭解(趕忙學!)程序員

1、SpringBoot的自動配置原理

不知道你們第一次搭SpringBoot環境的時候,有沒有以爲很是簡單。無須各類的配置文件,無須各類繁雜的pom座標,一個main方法,就能run起來了。與其餘框架整合也賊方便,使用EnableXXXXX註解就能夠搞起來了!github

因此今天來說講SpringBoot是如何實現自動配置的~spring

1.1三個重要的註解

咱們能夠發現,在使用main()啓動SpringBoot的時候,只有一個註解@SpringBootApplicationtomcat

只有一個@SpringBootApplication註解

咱們能夠點擊進去@SpringBootApplication註解中看看,能夠發現有三個註解是比較重要的:框架

SpringBootApplication註解詳情

  • @SpringBootConfiguration:咱們點進去之後能夠發現底層是Configuration註解,說白了就是支持JavaConfig的方式來進行配置(使用Configuration配置類等同於XML文件)。
  • @EnableAutoConfiguration:開啓自動配置功能(後文詳解)
  • @ComponentScan:這個註解,學過Spring的同窗應該對它不會陌生,就是掃描註解,默認是掃描當前類下的package。將@Controller/@Service/@Component/@Repository等註解加載到IOC容器中。

因此,Java3yApplication類能夠被咱們當作是這樣的:ide

@SpringBootConfiguration
@EnableAutoConfiguration
@ComponentScan
public class Java3yApplication {

    public static void main(String[] args) {
        SpringApplication.run(Java3yApplication.class, args);
    }
}
複製代碼

1.2重點EnableAutoConfiguration

咱們知道SpringBoot能夠幫咱們減小不少的配置,也確定聽過「約定大於配置」這麼一句話,那SpringBoot是怎麼作的呢?其實靠的就是@EnableAutoConfiguration註解。spring-boot

簡單來講,這個註解能夠幫助咱們自動載入應用程序所須要的全部默認配置

介紹有一句說:

if you have tomcat-embedded.jar on your classpath you are likely to want a TomcatServletWebServerFactory

若是你的類路徑下有tomcat-embedded.jar包,那麼你極可能就須要TomcatServletWebServerFactory

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

EnableAutoConfiguration註解詳情

  • @AutoConfigurationPackage:自動配置包
  • @Import:給IOC容器導入組件

1.2.1AutoConfigurationPackage

網上將這個@AutoConfigurationPackage註解解釋成自動配置包,咱們也看看@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來加載

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

跟蹤實現

簡單梳理:

  • FACTORIES_RESOURCE_LOCATION的值是META-INF/spring.factories
  • Spring啓動的時候會掃描全部jar路徑下的META-INF/spring.factories,將其文件包裝成Properties對象
  • 從Properties對象獲取到key值爲EnableAutoConfiguration的數據,而後添加到容器裏邊。

從Properties對象獲取到EnableAutoConfiguration.class對應的值,而後添加到容器裏邊

最後咱們會默認加載113個默認的配置類:

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

加載的配置類和文件的信息

1.3總結

@SpringBootApplication等同於下面三個註解:

  • @SpringBootConfiguration
  • @EnableAutoConfiguration
  • @ComponentScan

其中@EnableAutoConfiguration是關鍵(啓用自動配置),內部實際上就去加載META-INF/spring.factories文件的信息,而後篩選出以EnableAutoConfiguration爲key的數據,加載到IOC容器中,實現自動配置功能!

自動配置功能

官網文檔參考:

英語很差的同窗能夠像我同樣,對照着來看:

一邊插件,一邊原文

最後

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

帥的人都關注了

以爲個人文章寫得不錯,不妨點一下

相關文章
相關標籤/搜索