在SpringBoot中,有许多的AutoConfiguration类,例如RedisAutoConfiguration,DubboAutoConfiguration等,这个类,并不在@SpringBootApplication的扫描路径中,那么这些类的配置是怎么生效的呢,下面我们跟着源码看下。
一、入口
以前我们讲@Configuration的配置源码的时候,说过ConfigurationClassParse类的parse()方法。
在这个方法的最后一行代码就是入口:
processDeferredImportSelectors();
其实,这里面是用了@SpringBootApplication注解中的@EnableAutoConfiguration注解中的
关于这个AutoConfigurationImportSelector类是在我们以前分析@Configuration注解的时候载入进去的:
// Process any @Import annotations
processImports(configClass, sourceClass, getImports(sourceClass), true);
通过这个这个方法,就是将@SpringBootApplication注解上的@EnableAutoConfiguration注解上的AutoConfigurationImportSelector类解析使用了。
二、过程
接着我们继续返回方法processDeferredImportSelectors() ,这个方法中调用了getImports()方法,这个方法如下:
public Iterable<Group.Entry> getImports() {
for (DeferredImportSelectorHolder deferredImport : this.deferredImports) {
this.group.process(deferredImport.getConfigurationClass().getMetadata(),
deferredImport.getImportSelector());
}
return this.group.selectImports();
}
然后后面再group.process方法中,进入了方法:
selector.selectImports(metadata)
这个selector就是我们之前获取的AutoConfigurationImportSelector。然后进入了这个类的核心方法:getCandidateConfigurations。
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;
}
这个代码我们很熟悉,SpringFactoriesLoader就是加载Spring.factories文件中的类,这个加载的类型是:
protected Class<?> getSpringFactoriesLoaderFactoryClass() {
return EnableAutoConfiguration.class;
}
通过这个方式我们就把所有spring.factories中的所有AutoConfiguration加载进来了。