官术网_书友最值得收藏!

3.3 Spring Boot自動配置過程

Spring Boot內(nèi)置自動配置原理是怎樣的呢?這一切都在@EnableAutoConfiguration這個注解里:

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

其中的核心注解是@Import(EnableAutoConfigurationImportSelector.class),借助Enable-AutoConfigurationImportSelector、@EnableAutoConfiguration、Spring Boot應(yīng)用將所有符合條件的@Configuration配置類都加載到當前Spring容器中——就像一只“八爪魚”一樣。具體的實現(xiàn)是使用了Spring框架中原有的一個工具類SpringFactoriesLoader。這樣,@EnableAutoConfiguration就可以智能實現(xiàn)Bean的自動配置。

3.3.1 @EnableAutoConfiguration注解

Spring Boot中通過@EnableAutoConfiguration啟用Spring應(yīng)用程序上下文的自動配置,這個注解會導入一個EnableAutoConfigurationImportSelector的類,而AutoConfigurationImportSelector這個類會去讀取一個spring.factories下key為EnableAutoConfiguration對應(yīng)的類全限定名的值。其中的關(guān)鍵代碼如下:

        protected List<String> getCandidateConfigurations(AnnotationMetadata metadata,
        AnnotationAttributes attributes) {
    List<String> configurations = SpringFactoriesLoader.loadFactoryNames(
            getSpringFactoriesLoaderFactoryClass(), getBeanClassLoader());
    Assert.notEmpty(configurations,
            "No auto configuration classes found in META-INF/spring.factories.
                If you "
                    + "are using a custom packaging, make sure that file
                          is correct.");
    return configurations;
}

這個spring.factories里面配置的那些類,主要作用是告訴Spring Boot這個stareter所需要加載的那些*AutoConfiguration類,也就是你真正的要自動注冊的那些Bean或功能。然后,再實現(xiàn)一個spring.factories指定的類,標上@Configuration注解,一個starter就定義完了。通過org.springframework.boot.autoconfigure.AutoConfigurationImportSelector里面的getCandidateConfigurations方法,獲取到候選類的名字列表List<String>。

其中,loadFactoryNames的第1個參數(shù)是getSpringFactoriesLoaderFactoryClass()方法直接返回的是EnableAutoConfiguration.class,代碼如下:

              protected Class<? > getSpringFactoriesLoaderFactoryClass() {
                  return EnableAutoConfiguration.class;
              }

所以,getCandidateConfigurations方法里面的這段代碼:

        List<String> configurations = SpringFactoriesLoader.loadFactoryNames(
                          getSpringFactoriesLoaderFactoryClass(), getBeanClassLoader());

會過濾出key為

        org.springframework.boot.autoconfigure.EnableAutoConfiguration

的全限定名對應(yīng)的值。其中,SpringFactoriesLoader主要用來查詢META-INF/spring. factories的properties配置中指定class對應(yīng)的所有實現(xiàn)類。下節(jié)介紹這個文件。

提示

全限定名都使用如下命名方法:

包名.外部類名

包名.外部類名$內(nèi)部類名

例如:

            org.springframework.boot.autoconfigure.context.PropertyPlaceholderAutoConfi
                guration

3.3.2 spring.factories文件

Spring Boot中的META-INF/spring.factories(spring-boot/spring-boot-autoconfigure/src/main/resources/META-INF/spring.factories)配置文件的完整內(nèi)容可參考Spring Boot源代碼工程,其中關(guān)于EnableAutoConfiguration的配置是:

        # Auto Configure
        org.springframework.boot.autoconfigure.EnableAutoConfiguration=\
        org.springframework.boot.autoconfigure.admin.SpringApplicationAdminJmxAut
            oConfiguration, \
        ……
        org.springframework.boot.autoconfigure.webservices.WebServicesAutoConfiguration

當然了,這些AutoConfiguration不是所有都會加載的,會根據(jù)AutoConfiguration上的@ConditionalOnClass等條件,再進一步判斷是否加載。

3.3.3 獲取候選配置類

在上面的getCandidateConfigurations方法中,我們可以看到讀取spring.factories文件由SpringFactoriesLoader來完成的。SpringFactoriesLoader的實現(xiàn)類似于SPI(Service Provider Interface,在java.util.ServiceLoader的文檔里有比較詳細的介紹。Java SPI提供一種服務(wù)發(fā)現(xiàn)機制,為某個接口尋找服務(wù)實現(xiàn)的機制。有點類似IOC的思想,就是將裝配的控制權(quán)移到程序之外,在模塊化設(shè)計中這個機制尤其重要。

SpringFactoriesLoader會加載classpath下所有JAR文件里面的META-INF/spring.factories文件。

其中加載spring.factories文件的代碼在loadFactoryNames()方法里。Spring Boot自動配置的過程可以用一張圖說明,如圖3-3所示。

圖3-3 Spring Boot Autoconfigure工作原理圖

主站蜘蛛池模板: 常州市| 襄城县| 泽库县| 廉江市| 榆中县| 清流县| 桐梓县| 涞水县| 馆陶县| 松阳县| 巴东县| 开江县| 和田县| 屯门区| 财经| 秦皇岛市| 中牟县| 镇远县| 犍为县| 林周县| 南木林县| 水城县| 祁门县| 凌源市| 兴安盟| 安西县| 普宁市| 玉环县| 娱乐| 镇远县| 清流县| 香格里拉县| 资阳市| 大连市| 麻栗坡县| 象山县| 谢通门县| 安溪县| 福海县| 安吉县| 辰溪县|