Spring Boot 啟動類上一個 @SpringBootApplication 注解是
- @SpringBootConfiguration
- @EnableAutoConfiguration
- @ComponentScan
三個注解組成的一個復(fù)合注解夭问。其中 @SpringBootConfiguration 其實也是和@Configuration 注解組成的一個組合注解,功能也是和 @Configuration 相同苟穆;@ComponentScan 這個注解是標(biāo)注需要掃描的包。今天著重說一下 @EnableAutoConfiguration 注解唱星。
其實 @EnableAutoConfiguration 注解也和其它 @Enable*
注解一脈相乘的雳旅,簡單說一下就是借助 @Import 的支持,收集和注冊特定場景相關(guān)的Bean的定義:比如:@EnableAspectJAutoProxy 就是通過@Import 注解動態(tài)的將Bean注冊到 SpringIoc
容器中间聊,而@EnableAutoConfiguration 是借助 @Import 把所有符合條件的 Bean 加載到
SpringIoc 容器中攒盈。
1、@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 幫助Spring Boot 應(yīng)用將所有符合條件的 @Configuration 配置加載到當(dāng)前IoC容器中。而最主要的還是借助于 Spring 框架一的一個工具類:SpringFactoriesLoader 將 META-INF/spring.factories加載配置尚蝌,spring.factories 文件是一個典型的properties配置文件迎变,配置的格式仍然是Key = Value 的形式,中不過 Key 和 Value 都是Java的完整類名飘言。比如:org.springframework.data.repository.core.support.RepositoryFactorySupport=org.springframework.data.jpa.repository.support.JpaRepositoryFactory
2衣形、AutoConfigurationImportSelector 源碼
@Override
public String[] selectImports(AnnotationMetadata annotationMetadata) {
if (!isEnabled(annotationMetadata)) {
return NO_IMPORTS;
}
AutoConfigurationMetadata autoConfigurationMetadata = AutoConfigurationMetadataLoader
.loadMetadata(this.beanClassLoader); //1
AutoConfigurationEntry autoConfigurationEntry = getAutoConfigurationEntry(
autoConfigurationMetadata, annotationMetadata); //2
return StringUtils.toStringArray(autoConfigurationEntry.getConfigurations());
}
- 1.獲取注解信息
- 2.獲取所有配置列表
其中 AutoConfigurationMetadataLoader.loadMetadata方法源碼
public static AutoConfigurationMetadata loadMetadata(ClassLoader classLoader) {
return loadMetadata(classLoader, PATH);
}
static AutoConfigurationMetadata loadMetadata(ClassLoader classLoader, String path) {
try {
Enumeration<URL> urls = (classLoader != null) ? classLoader.getResources(path)
: ClassLoader.getSystemResources(path);
Properties properties = new Properties();
while (urls.hasMoreElements()) {
properties.putAll(PropertiesLoaderUtils
.loadProperties(new UrlResource(urls.nextElement())));
}
return loadMetadata(properties);
}
catch (IOException ex) {
throw new IllegalArgumentException(
"Unable to load @ConditionalOnClass location [" + path + "]", ex);
}
}
getAutoConfigurationEntry 方法:
protected AutoConfigurationEntry getAutoConfigurationEntry(
AutoConfigurationMetadata autoConfigurationMetadata,
AnnotationMetadata annotationMetadata) {
if (!isEnabled(annotationMetadata)) {
return EMPTY_ENTRY;
}
//1.
AnnotationAttributes attributes = getAttributes(annotationMetadata);
//2.
List<String> configurations = getCandidateConfigurations(annotationMetadata,
attributes);
//3.
configurations = removeDuplicates(configurations);
//4.
Set<String> exclusions = getExclusions(annotationMetadata, attributes);
checkExcludedClasses(configurations, exclusions);
configurations.removeAll(exclusions);
configurations = filter(configurations, autoConfigurationMetadata);
//5.
fireAutoConfigurationImportEvents(configurations, exclusions);
return new AutoConfigurationEntry(configurations, exclusions);
}
- 1.獲取注解上所有屬性信息
- 2.獲取候選配置列表 [核心步驟]
通過SpringFactoriesLoader.loadFactoryNames獲取配置信息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; }
- 3.去重
- 4.配置exclude 信息去除不需要的
- 5.派發(fā)事件