詳解Spring Boot 自動配置機制

詳解Spring Boot 自動配置機制

一、簡介

Spring boot 是一個基於 Spring框架開發,高於 Spring 框架,它對 Spring 做了更好的封裝,提供了更多的產品級特性,極大的提升了 Spring 的可用性。

Spring 的配置一直都是詬病,直到 Java Config 推出之後,得到了很大的改善,但Java Config 也存在很多問題,例如:開發人員往往找不到配置到底在哪!

Spring Boot 統一了配置模式(application.yml),並且提供了很多的默認配置,讓我們可以有更多的時間關注業務邏輯;當需要進行擴展或者進行修改的時,又不失靈活性。

二、Spring Boot 自動配置

Spring Boot 自動配置的目標是通過 jar 包的依賴,自動配置應用程序。

詳解Spring Boot 自動配置機制

做到這一點,Spring Boot 使用了一個很多人都不知道的類:SpringFactoriesLoader

詳解Spring Boot 自動配置機制

SpringFactoriesLoader 是一個抽象類,他會通過loadFactories/loadFactoryNames加載每個 jar 包中META-INF/spring.factories文件。

詳解Spring Boot 自動配置機制

spring.factories如上圖所示,該文件是spring-boot-autoconfigure-1.5.8.RELEASE.jar包中META-INF/spring.factories的內容,其實就是一個屬性文件,左側通常為一個接口或者是一個註解類,右側為接口的實現,或者是和左值相關的註解。

Spring Boot 自動配置就是加載spring.factories中EnableAutoConfiguration下配置的所有的配置源,並註冊到 Spring 的 ApplicationContext 上去,瞭解了這個機制後,我們就可以按照自己的需求定製自動配置。

在我們的 EOS8 微服務平臺中,我們就使用到這種配置方式:

詳解Spring Boot 自動配置機制

三、Spring Boot 自帶自動配置

Spring Boot 的自動配置模塊spring-boot-autoconfigure,幾乎提供了我們常見Spring 整合框架的所有的自動配置功能,例如:database、JPA、security、session 等等;

在官網上可以找到一個列表,我們可以去方便的查看,按照項目需求進行使用:

https://docs.spring.io/spring-boot/docs/1.5.9.RELEASE/reference/htmlsingle/#auto-configuration-classes-from-autoconfigure-module

當然,我們也可以找到對應的配置類,以方便我們可以更好的瞭解配置項。

四、Condition和@Conditional

Spring Boot 的autoconfigure機會囊括了所有的可以和Spring 整合的項目,這樣做的最大好處是,我們不用再去為版本的兼容性而煩惱,只要按照官方推薦的版本,加入依賴的 jar 就可以;

但通常情況下,這麼多的功能,並不是都需要,Spring Boot 靈活的使用 Spring 的條件配置,讓 Spring Boot 的自動配置,只有在滿足指定條件的情況下才會生效。

通常情況下,判斷條件有如下幾種情況:

  • 判斷 classpath 中是否存在指定的類

  • 判斷 ApplicationContext 中是否存在指定的 Bean

  • 配置環境中是否存在特定的配置項

  • 配置環境中指定的配置項是否存在指定的值

當然,我們也可以通過自定義Condition接口的實現,使用@Conditional註解指定;

Spring Boot 中自定義了很多的條件註解類:

詳解Spring Boot 自動配置機制

通過這些註解的名稱,我們就很容易知道他們的含義。

五、禁用默認配置

如果我們不想使用默認的配置,但是默認的配置又滿足啟用的條件,應用啟動的時候,配置也生效,這個時候,我們可以通過下面的方式來禁用默認配置:

詳解Spring Boot 自動配置機制

或者,直接這樣:

詳解Spring Boot 自動配置機制

六、Spring Boot 配置源的加載

Spring Boot加載配置源是以 Spring 為基礎的; 適用於 Spring 的配置源,均適用於 Spring Boot,如:xml、groovy、java config 等。

Spring 在啟動 ApplicationContext 的時候,需要明確指定啟動的配置文件或者配置類;

Spring Boot 是在啟動 SpringApplication 之前,預先配置環境資源和屬性變量,然後使用BeanDefinitionLoader加載配置源,並註冊到BeanDefinitionRegistry;

Spring Boot 對Spring BeanDefinitionReader進行了封裝,o.s.boot. BeanDefinitionLoader, 它對Class、xml、Package、Groovry 的配置源,做了一個統一的適配。所以,可以在SpringApplication.run(Object[] configSource,String … args)方法中傳入以上各種類型。

七、Spring配置是怎麼加載

Spring對不同類型的配置源會使用不同類型的BeanDefinitionReader對其進行加載。

詳解Spring Boot 自動配置機制

例如:xml 文件使用XmlBeanDefinitionReader,Groovy 使用GroovyBeanDefinitionReader;註解類使用AnnotatedBeanDefinitionReader,所不同的是AnnotatedBeanDefinitionReader並不是BeanDefinitionReader的實現類。

Spring 強大的註解掃描和註解解析能力:

Spring使用ClassPathBeanDefinitionScanner類,掃描classpath 中的註解類,在開始doScan之前,可以調用該類的addIncludeFilter和addExcludeFilter註冊TypeFilter,來指定讓該類掃描哪些類,和不掃描哪些類;

Spring 默認註冊掃描@Component註解的所有類。

Spring 為什麼沒有把其他的註解類也註冊到過濾器去呢?

Spring 的註解處理機制具有傳遞性,只要是被@Component註解的註解,都會進行掃描解析,例如我們常見的:@Service、@Controller、@Repository、@Configuration 等註解類,都是由@Component,因此,我們也可以使用這個機制進行自定義註解。

八、我們EOS8 用到了哪些

Spring/Spring Boot配置能力呢?

  • 在平臺的功能模塊加載中,我們使用spring.factories,用做模塊自動配置。

  • 在微服務消費端加載微服務的代理時,使用到了自定義的Annotation。

  • 使用配置特定的參數,啟動是 cloud 模式,還是開發模式。

九、總結

Spring Boot的自動配置很簡單,主要總結為以下三步:

1. 在spring.factories的註冊後,實現跨 jar 包自動加載

2. 基於 Condition 來實現條件配置

3. 自定義註解實現個性化擴展

詳解Spring Boot 自動配置機制

關於作者虎振東,普元SOA&雲計算部門資深軟件工程師,8年軟件開發設計經驗,曾在歌華數媒架構設計開發多個廣電和移動互聯網融合項目,普元 EOS 8微服務平臺核心開發工程師。


分享到:


相關文章: