自动配置原理
自动配置源码流程图
自动配置源码解析
@SpringBootApplication
spring boot提供的注解,标明是spring boot项目,进入此注解
@Target(ElementType.TYPE)
@Retention(RetentionPolicy.RUNTIME)
@Documented
@Inherited
@SpringBootConfiguration
//开启自动配置类注解 ***重点***
@EnableAutoConfiguration
@ComponentScan(excludeFilters = { @Filter(type = FilterType.CUSTOM, classes = TypeExcludeFilter.class),
@Filter(type = FilterType.CUSTOM, classes = AutoConfigurationExcludeFilter.class) })
public @interface SpringBootApplication {
//排除指定自动注入配置类
@AliasFor(annotation = EnableAutoConfiguration.class)
Class<?>[] exclude() default {};
//排除指定自动注入配置类名
@AliasFor(annotation = EnableAutoConfiguration.class)
String[] excludeName() default {};
//ComponentScan的别名,可以设置扫描包路径
@AliasFor(annotation = ComponentScan.class, attribute = "basePackages")
String[] scanBasePackages() default {};
//扫描指定类
@AliasFor(annotation = ComponentScan.class, attribute = "basePackageClasses")
Class<?>[] scanBasePackageClasses() default {};
...
}
@EnableAutoConfiguration
开启自动配置,自动扫描项目中所有jar包中的META-INF/spring.factories文件中的EnableAutoConfiguration对应的类名,将这些类当成配置类载入spring容器
@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)
实现DeferredImportSelector接口,此接口spring会延迟加载,在所有配置都加载完才会加载此类
当前类的Ordered 设置为Ordered.LOWEST_PRECEDENCE - 1,表示如果存在其他DeferredImportSelector,当前类的优先级比最低优先级高一级
public class AutoConfigurationImportSelector implements DeferredImportSelector, BeanClassLoaderAware,
ResourceLoaderAware, BeanFactoryAware, EnvironmentAware, Ordered {
...
/***
* 通常ImportSelector都是重写selectImports来告诉spring导入类都有哪些
**但是当前类,通过重写getImportGroup,返回AutoConfigurationGroup,spring会调用此类的process方法获取导入类
**/
@Override
public String[] selectImports(AnnotationMetadata annotationMetadata) {
if (!isEnabled(annotationMetadata)) {
return NO_IMPORTS;
}
AutoConfigurationEntry autoConfigurationEntry = getAutoConfigurationEntry(annotationMetadata);
return StringUtils.toStringArray(autoConfigurationEntry.getConfigurations());
}
...
/***
* 通知spring通过AutoConfigurationGroup类载入配置类
*/
@Override
public Class<? extends Group> getImportGroup() {
return AutoConfigurationGroup.class;
}
}
AutoConfigurationGroup.process
获取配置和返回给spring需要导入的类
private static class AutoConfigurationGroup
implements DeferredImportSelector.Group, BeanClassLoaderAware, BeanFactoryAware, ResourceLoaderAware {
...
/***
* 调用getAutoConfigurationEntry方法获取需要自动注入的配置类
*/
@Override
public void process(AnnotationMetadata annotationMetadata, DeferredImportSelector deferredImportSelector) {
Assert.state(deferredImportSelector instanceof AutoConfigurationImportSelector,
() -> String.format("Only %s implementations are supported, got %s",
AutoConfigurationImportSelector.class.getSimpleName(),
deferredImportSelector.getClass().getName()));
AutoConfigurationEntry autoConfigurationEntry = ((AutoConfigurationImportSelector) deferredImportSelector)
.getAutoConfigurationEntry(annotationMetadata);
this.autoConfigurationEntries.add(autoConfigurationEntry);
for (String importClassName : autoConfigurationEntry.getConfigurations()) {
this.entries.putIfAbsent(importClassName, annotationMetadata);
}
}
...
/***
* 此类返回注入的配置类
*/
@Override
public Iterable<Entry> selectImports() {
if (this.autoConfigurationEntries.isEmpty()) {
return Collections.emptyList();
}
//获取配置中配置了排除的文件,排除掉
Set<String> allExclusions = this.autoConfigurationEntries.stream()
.map(AutoConfigurationEntry::getExclusions).flatMap(Collection::stream).collect(Collectors.toSet());
//
Set<String> processedConfigurations = this.autoConfigurationEntries.stream()
.map(AutoConfigurationEntry::getConfigurations).flatMap(Collection::stream)
.collect(Collectors.toCollection(LinkedHashSet::new));
processedConfigurations.removeAll(allExclusions);
return sortAutoConfigurations(processedConfigurations, getAutoConfigurationMetadata()).stream()
.map((importClassName) -> new Entry(this.entries.get(importClassName), importClassName))
.collect(Collectors.toList());
}
}
getAutoConfigurationEntry
获取自动配置类,每个配置类保证成AutoConfigurationEntry对象
protected AutoConfigurationEntry getAutoConfigurationEntry(AnnotationMetadata annotationMetadata) {
if (!isEnabled(annotationMetadata)) {
return EMPTY_ENTRY;
}
AnnotationAttributes attributes = getAttributes(annotationMetadata);
//获取所有jar下的EnableAutoConfiguration
List<String> configurations = getCandidateConfigurations(annotationMetadata, attributes);
//去重
configurations = removeDuplicates(configurations);
//获取@SpringBootApplication注解上排除的配置类
Set<String> exclusions = getExclusions(annotationMetadata, attributes);
//spring.autoconfigure.exclude配置的也排除
checkExcludedClasses(configurations, exclusions);
//排除配置类
configurations.removeAll(exclusions);
// 通过读取spring.factories 中的OnBeanCondition\OnClassCondition\OnWebApplicationCondition进行过滤
configurations = getConfigurationClassFilter().filter(configurations);
//触发事件通知
fireAutoConfigurationImportEvents(configurations, exclusions);
//返回筛选后的
return new AutoConfigurationEntry(configurations, exclusions);
}
getCandidateConfigurations
获取所有jar下面META-INF/spring.factories文件中的EnableAutoConfiguration对应的集合(此集合从缓存中取,项目启动时第一次访问时,将所有配置对应的key-value加载到缓存中)
protected List<String> getCandidateConfigurations(AnnotationMetadata metadata, AnnotationAttributes attributes) {
//获取EnableAutoConfiguration对应的值
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;
}