頭禿了,Spring Boot 自動配置源碼解析瞭解一波~

持續原創輸出,點擊上方藍字關注我

目錄

  • 前言
  • 源碼版本
  • @SpringBootApplication幹了什麼?
  • @EnableAutoConfiguration幹了什麼?
  • 總結

前言

爲什麼Spring Boot這麼火?因爲便捷,開箱即用,但是你思考過爲什麼會這麼便捷嗎?傳統的SSM架構配置文件至少要寫半天,而使用Spring Boot之後只需要引入一個starter之後就能直接使用,why???

原因很簡單,每個starter內部做了工作,比如Mybatis的啓動器默認內置了可用的SqlSessionFactory

至於如何內置的?Spring Boot 又是如何使其生效的?這篇文章就從源碼角度介紹一下Spring Boot的自動配置原理。

源碼版本

作者Spring Boot是基於2.4.0。每個版本有些變化,讀者儘量和我保持一致,以防源碼有些出入。

@SpringBootApplication幹了什麼?

這麼說吧,這個註解什麼也沒做,廢物,活都交給屬下做了,源碼如下:

@Target(ElementType.TYPE)
@Retention(RetentionPolicy.RUNTIME)
@Documented
@Inherited
@SpringBootConfiguration
@EnableAutoConfiguration
@ComponentScan(excludeFilters = { @Filter(type = FilterType.CUSTOM, classes = TypeExcludeFilter.class),
  @Filter(type 
= FilterType.CUSTOM, classes = AutoConfigurationExcludeFilter.class) })
public @interface SpringBootApplication 
{}

上方標註了三個重要的註解,如下:

  1. @SpringBootConfiguration:其實就是@Configuration,因此主啓動類可以當做配置類使用,比如注入Bean等。
  2. @EnableAutoConfiguration:這個註解牛批了,名字就不一樣,開啓自動配置,哦,關鍵都在這了.....
  3. @ComponentScan:包掃描註解。

經過以上的分析,最終定位了一個註解@EnableAutoConfiguration,顧名思義,肯定和自動配置有關,要重點分析下。

@EnableAutoConfiguration幹了什麼?

想要知道做了什麼肯定需要看源碼,如下:

@Target(ElementType.TYPE)
@Retention(RetentionPolicy.RUNTIME)
@Documented
@Inherited
@AutoConfigurationPackage
@Import(AutoConfigurationImportSelector.class)
public @interface EnableAutoConfiguration 
{}

上方標註了兩個重要的註解,如下:

  1. @AutoConfigurationPackage:自動配置包註解,默認將主配置類(@SpringBootApplication)所在的包及其子包裏面的所有組件掃描到IOC容器中。
  2. @Import:該註解不必多說了,前面文章說過很多次了,這裏是導入了AutoConfigurationImportSelector,用來注入自動配置類。

以上只是簡單的分析了兩個註解,下面將會從源碼詳細的介紹一下。

@AutoConfigurationPackage

這個註解幹了什麼?這個需要看下源碼,如下;

@Target(ElementType.TYPE)
@Retention(RetentionPolicy.RUNTIME)
@Documented
@Inherited
@Import(AutoConfigurationPackages.Registrar.class)
public @interface AutoConfigurationPackage 
{}

重要的還是@Import註解,導入了AutoConfigurationPackages.Registrar,這個類是幹什麼的?源碼如下圖:

其實就兩個方法,但是的最重要的就是registerBeanDefinitions方法,但是這個方法不用看,肯定是注入Bean,這裏的重點是注入哪些Bean,重點源碼如下:

//獲取掃描的包
new PackageImports(metadata).getPackageNames().toArray(new String[0])

跟進代碼,主要邏輯都在#PackageImports.PackageImports()這個構造方法中,源碼解析如下圖:

從上面源碼分析可以知道,這裏掃描的包名是由兩部分組成,分別如下:

  1. @AutoConfigurationPackage註解中的兩個屬性解析得來的包名。
  2. 註解AutoConfigurationPackage所在的包名,即是@SpringBootApplication所在的包名。

@AutoConfigurationPackage默認將主配置類(@SpringBootApplication)所在的包及其子包裏面的所有組件掃描到IOC容器中。

@Import(AutoConfigurationImportSelector.class)

這個註解不用多說了,最重要的就是AutoConfigurationImportSelector,我們來看看它的繼承關係,如下圖:

這個類的繼承關係還是挺簡單的,實現了Spring中的xxAware注入一些必要的組件,但是最值得關心的是實現了一個DeferredImportSelector這個接口,這個接口擴展了ImportSelector,也改變了其運行的方式,這個在後面章節會介紹。

注意:這個類會導致一個誤區,平時看到xxxSelector已經有了反射弧了,肯定會在selectImports()方法上DEBUG,但是這個類壓根就沒執行該方法,我第一次看也有點懷疑人生了,原來它走的是DeferredImportSelector的接口方法。

其實該類真正實現邏輯的方法是process()方法,但是主要加載自動配置類的任務交給了getAutoConfigurationEntry()方法,具體的邏輯如下圖:

上圖的邏輯很簡單,先從spring.factories文件中獲取自動配置類,在去掉@SpringBootApplication中定義排除的自動配置類。

上圖中的第步就是從META-INF/spring.factories中加載自動配置類,代碼很簡單,在上一篇分析啓動流程的時候也有很多組件是從spring.facotries文件中加載的,代碼都類似。

springboot-autoconfigure中的spring.facotries文件內置了很多自動配置類,如下:

# Auto Configure
org.springframework.boot.autoconfigure.EnableAutoConfiguration=\
org.springframework.boot.autoconfigure.admin.SpringApplicationAdminJmxAutoConfiguration,\
org.springframework.boot.autoconfigure.aop.AopAutoConfiguration,\
org.springframework.boot.autoconfigure.amqp.RabbitAutoConfiguration,\
org.springframework.boot.autoconfigure.batch.BatchAutoConfiguration,\
org.springframework.boot.autoconfigure.cache.CacheAutoConfiguration,\
org.springframework.boot.autoconfigure.cassandra.CassandraAutoConfiguration,\
org.springframework.boot.autoconfigure.context.ConfigurationPropertiesAutoConfiguration,\
org.springframework.boot.autoconfigure.context.LifecycleAutoConfiguration,\
org.springframework.boot.autoconfigure.context.MessageSourceAutoConfiguration,\
org.springframework.boot.autoconfigure.context.PropertyPlaceholderAutoConfiguration,\
................

瞭解了Spring Boot 如何加載自動配置類,那麼自定義一個自動配置類也是很簡單了,後續章節教你如何定製自己的自動配置類,裏面還是有很多門道的.....

總結

本文從源碼角度分析了Spring Boot的自動配置是如何加載的,其實分析起來很簡單,希望作者的這篇文章能幫助你更深層次的瞭解Spring Boot

另外作者的第一本PDF書籍已經整理好了,由淺入深的詳細介紹了Mybatis基礎以及底層源碼,有需要的朋友公號回覆關鍵詞Mybatis進階即可獲取,目錄如下:

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章