SpringBoot自動裝配原理


本文是基於《Spring cloud Alibaba微服務原理與實戰》(作者:譚鋒)一書中關於SpringBoot的自動裝配原理學習了解的。

1、springBoot自動裝配的實現 

  通過IDEA創建一個SpringBoot工程后(或其他方式),就會在主啟動類的上方發現@SpringBootApplication這個注解,其實這個注解就像是一個封裝的方法。要進入到該注解中去,會發現有一個@EnableAutoConfiguration注解,見名知意,@EnableAutoConfiguration就是用來開啟SpringBoot的自動裝配的注解。

 1 @SpringBootApplication  2 public class StaterApplication {  3 
 4     public static void main(String[] args) {  5         SpringApplication.run(StaterApplication.class, args);  6  }  7 
 8 }


9 @Target({ElementType.TYPE}) 10 @Retention(RetentionPolicy.RUNTIME) 11 @Documented 12 @Inherited 13 @SpringBootConfiguration 14 @EnableAutoConfiguration 15 @ComponentScan( 16 excludeFilters = {@Filter( 17 type = FilterType.CUSTOM, 18 classes = {TypeExcludeFilter.class} 19 ), @Filter( 20 type = FilterType.CUSTOM, 21 classes = {AutoConfigurationExcludeFilter.class} 22 )} 23 ) 24 public @interface SpringBootApplication { 25 .... 26 }

   接着再進入@EnableAutoConfiguration,有兩個重要的注解

     ①、@AutoConfigurationPackage : 作用是把使用了該注解的類所在包以及子包下的所有組件掃描到spring IOC容器中   這也是為什么在創建SpringBoot項目時,一定要把controller、service等都要與主啟動類放在同一級目錄的原因。

     ②、@Import({AutoConfigurationImportSelector.class})  這個注解才是自動裝配的重點,AutoConfigurationImportSelector這個類會實現配置類的導入,導入方式與@Configuration有一定的區別。

    AutoConfigurationImportSelector實現了ImportSelector,它只有一個selectImports方法,返回一個String[]數組,這個數組中可以指定需要裝配到IOC容器的類,當在@Import中導入一個ImportSelector的實現類之后,會把該實現類中返回的Class都裝配到IoC容器中。和@Configuration不同的是,ImportSelector可以實現批量裝配,並且還可以通過邏輯處理來實現Bean的選擇性裝配,也就是很具上下文環境來決定哪些類能夠被IoC初始化。

  1.1簡單使用ImportSelector

   首先創建兩個類,要把這兩個類裝配到Ioc容器中

public class FirstClass{ } public class SecondClass{ }

   創建一個ImportSelector的實現類,把上述定義的兩個Bean加入到String數組,意味着兩個Bean會裝配到Ioc中

 

 

    自定義一個注解,模擬@EnableAutoConfiguration,通過@Import導入GpImportSelector.

   

 

 

    創建一個啟動類,在該類上使用@EnableAutoImport注解后,就可以從Ioc容器中取得FirstClass對象的實例。

 

 

    這種實現方式相比@Import(*Configuration.class)的好處在於裝配的靈活性,還可以實現批量裝配,比如在G平ImportSelector還可以直接在String數組中定義多個Configuration類,由於一個配置代表的是某一個組件中批量的Bean聲明,所以自動裝配過程中只需要掃描到指定路徑下的配置類即可。

2、自動裝配原理分析

   定位到AutoConfigurationImportSeletor中的selectImpots方法,他是ImportSelector的實現,該方法主要有兩個功能:

    ①、AutoConfigurationMetadataLoader.loadMetadata從META-INFO/spring-autoconfigure-metadata.properties中加載自動裝配的條件的元數據,就是滿足條件的Bean才能夠進行裝配。

    ②、autoConfigurationEntry.getConfigurations()收集所有符合條件的配置類,完成自動裝配

             需要注意的是,AutoConfigurationImportSeletor中不執行selectImports方法,而是通過ConfigurationClassPostProcessor中的processConfigBeanDefinitions方法來掃描和注冊所有的配置類的Bean,最終調用getAutoConfigurationEntry方法來獲得所有需要自動裝配的配置類。

    以下是getAutoConfigurationEntry方法中幾個重要的方法:

protected AutoConfigurationImportSelector.AutoConfigurationEntry getAutoConfigurationEntry(AnnotationMetadata annotationMetadata) {
    if (!this.isEnabled(annotationMetadata)) {
return EMPTY_ENTRY;
} else {
AnnotationAttributes attributes = this.getAttributes(annotationMetadata);//獲得@EnableAutoConfiguration注解的屬性exclude、excludeName等

    List<String> configurations = this.getCandidateConfigurations(annotationMetadata, attributes);//獲得候選的自動裝配的配置類
 configurations = this.removeDuplicates(configurations);//去除重復配置項

Set<String> exclusions = this.getExclusions(annotationMetadata, attributes);
//根據@EnableAutoConfiguration注解的屬性exclude等屬性,把不需要自動裝配的移除

this.checkExcludedClasses(configurations, exclusions);
configurations.removeAll(exclusions);
configurations = this.getConfigurationClassFilter().filter(configurations);
this.fireAutoConfigurationImportEvents(configurations, exclusions);
return new AutoConfigurationImportSelector.AutoConfigurationEntry(configurations, exclusions);
}
}

    總的來說就是,先獲取所有的配置類,通過去重、exclude排除等操作,得到最終需要自動裝配的配置類。

    getCandidateConfigurations這個方法中使用到了SpringFactoriesLoader,會掃描classpath下的META-INFO/spring.factories文件,spring.factories文件中的數據以key=value形式存儲,而SpringFactoriesLoader.loaderFactoryName會根據Key得到對應的value值,因此,key對應為EnableAutoConfiguration,Value是多個配置類,也就是getCandidateConfigurations返回的值。

 

 

 省略。。。。。

另外還使用了許多@ConditionXXX的條件裝配的注解

 

 

 

至此,自動裝配的原理就分析完了,簡單總結一下:

  ①、通過@Import(AutoConfigurationImportSelector.class),導入配置類,這里並不是單個配置類的導入

  ②、AutoConfigurationImportSelector實現了ImportSelector類,重寫了selectImports方法,用於實現選擇性的批量配置類的裝配

  ③、通過Spring的SpringFactoryLoader機制,掃描classpath下的META/spring.factories文件,讀取需要實現自動裝配的配置類

  ④、通過條件篩選,把不符合的移除,最終實現自動裝配

 

 

 

 


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM