SpringBoot自動配置原理

菜鳥全棧BeeStack發表於2021-10-21

前言

只有光頭才能變強。

文字已收錄至我的GitHub倉庫,歡迎Star:github.com/ZhongFuChen…

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

作為一名Java程式設計師,就不可能不瞭解SpringBoot,如果不瞭解(趕緊學!)

一、SpringBoot的自動配置原理

不知道大家第一次搭SpringBoot環境的時候,有沒有覺得非常簡單。無須各種的配置檔案,無須各種繁雜的pom座標,一個main方法,就能run起來了。與其他框架整合也賊方便,使用EnableXXXXX註解就可以搞起來了!

所以今天來講講SpringBoot是如何實現自動配置的~

1.1三個重要的註解

我們可以發現,在使用main()啟動SpringBoot的時候,只有一個註解@SpringBootApplication

只有一個@SpringBootApplication註解

我們可以點選進去@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

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

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個預設的配置類:

SpringBoot自動配置原理

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

載入的配置類和檔案的資訊

1.3總結

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

  • @SpringBootConfiguration
  • @EnableAutoConfiguration
  • @ComponentScan

其中@EnableAutoConfiguration是關鍵(啟用自動配置),內部實際上就去載入META-INF/spring.factories檔案的資訊,然後篩選出以EnableAutoConfiguration為key的資料,載入到IOC容器中,實現自動配置功能!

自動配置功能

官網文件參考:

英語不好的同學可以像我一樣,對照著來看:

一邊外掛,一邊原文

最後

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

帥的人都關注了

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

相關文章