@EnableAutoConfiguration的說明


 springboot版本為2.0.7

@SpringBootApplication引入@EnableAutoConfiguration 

@Target({ElementType.TYPE})
@Retention(RetentionPolicy.RUNTIME)
@Documented
@Inherited
@AutoConfigurationPackage
@Import({AutoConfigurationImportSelector.class})
public @interface EnableAutoConfiguration {
    String ENABLED_OVERRIDE_PROPERTY = "spring.boot.enableautoconfiguration";

    Class<?>[] exclude() default {};

    String[] excludeName() default {};
}

@Import(AutoConfigurationImportSelector.class),借助AutoConfigurationImportSelector,@EnableAutoConfiguration可以幫助SpringBoot應用將所有符合條件的@Configuration配置都加載到當前SpringBoot創建並使用的IoC容器。

借助於Spring框架原有的一個工具類:SpringFactoriesLoader的支持,@EnableAutoConfiguration可以智能的自動配置功效才得以大功告成!

在AutoConfigurationImportSelector類中可以看到通過 SpringFactoriesLoader.loadFactoryNames()
把 spring-boot-autoconfigure.jar/META-INF/spring.factories中每一個xxxAutoConfiguration文件都加載到容器中,spring.factories文件里每一個xxxAutoConfiguration文件一般都會有下面的條件注解:

@ConditionalOnClass : classpath中存在該類時起效
@ConditionalOnMissingClass : classpath中不存在該類時起效
@ConditionalOnBean : DI容器中存在該類型Bean時起效
@ConditionalOnMissingBean : DI容器中不存在該類型Bean時起效
@ConditionalOnSingleCandidate : DI容器中該類型Bean只有一個或@Primary的只有一個時起效
@ConditionalOnExpression : SpEL表達式結果為true時
@ConditionalOnProperty : 參數設置或者值一致時起效
@ConditionalOnResource : 指定的文件存在時起效
@ConditionalOnJndi : 指定的JNDI存在時起效
@ConditionalOnJava : 指定的Java版本存在時起效
@ConditionalOnWebApplication : Web應用環境下起效
@ConditionalOnNotWebApplication : 非Web應用環境下起效

public String[] selectImports(AnnotationMetadata annotationMetadata) {
    if (!this.isEnabled(annotationMetadata)) {
        return NO_IMPORTS;
    } else {
        // 從配置文件中加載 AutoConfigurationMetadata
        AutoConfigurationMetadata autoConfigurationMetadata = AutoConfigurationMetadataLoader.loadMetadata(this.beanClassLoader);
        // 獲取注解的屬性值
        AnnotationAttributes attributes = this.getAttributes(annotationMetadata);
        // 獲取所有候選配置類EnableAutoConfiguration
        // 使用了內部工具使用SpringFactoriesLoader,查找classpath上所有jar包中的
        // META-INF\spring.factories,找出其中key為
        // org.springframework.boot.autoconfigure.EnableAutoConfiguration 
        // 的屬性定義的工廠類名稱。
        // 雖然參數有annotationMetadata,attributes,但在 AutoConfigurationImportSelector 的
        // 實現 getCandidateConfigurations()中,這兩個參數並未使用
        List<String> configurations = this.getCandidateConfigurations(annotationMetadata, attributes);
        // 去重    
        configurations = this.removeDuplicates(configurations);
        // 應用 exclusion 屬性
        Set<String> exclusions = this.getExclusions(annotationMetadata, attributes);
        // 對於不屬於AutoConfiguration的exclude報錯
        this.checkExcludedClasses(configurations, exclusions);
        // 從configurations去除exclusions
        configurations.removeAll(exclusions);
        // 應用過濾器AutoConfigurationImportFilter,
        // 對於 spring boot autoconfigure,定義了一個需要被應用的過濾器 :
        // org.springframework.boot.autoconfigure.condition.OnClassCondition,
        // 此過濾器檢查候選配置類上的注解@ConditionalOnClass,如果要求的類在classpath
        // 中不存在,則這個候選配置類會被排除掉
        configurations = this.filter(configurations, autoConfigurationMetadata);
        // 現在已經找到所有需要被應用的候選配置類
        // 廣播事件 AutoConfigurationImportEvent
        this.fireAutoConfigurationImportEvents(configurations, exclusions);
        return StringUtils.toStringArray(configurations);
    }
}


免責聲明!

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



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