引言
@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 {};
}
今天,我们就聊聊@EnableAutoConfiguration的处理逻辑。
找核心方法
@Enable开头的的注解上一般都有@Import用于指定要注解的逻辑实现类。
@EnableAutoConfiguration上的@Import,导入的是 AutoConfigurationImportSelector。
AutoConfigurationImportSelector就是要找的入口类。 类关系如下:
public class AutoConfigurationImportSelector implements DeferredImportSelector, BeanClassLoaderAware, ResourceLoaderAware, BeanFactoryAware, EnvironmentAware, Ordered
Aware系列都是用于注入响应的资源,Ordered用于排序。
值得关注的是 DeferredImportSelector,查看其类注释,简要翻译如下:
importselector的变体,在所有@Configuration bean之后运行,可以实现Ordered进行排序。
提供{getImportGroup(),它可以跨不同的选择器提供额外的排序和过滤逻辑。
DeferredImportSelector保证在所有@Configuration加载之后执行,也就是说,如果有相关配置类已加载,则可以跳过自动装配类。
DeferredImportSelector是如何保证在@Configuration bean加载之后执行的呢???
带着这个疑问,我查看了ConfigurationClassPostProcessor#processConfigBeanDefinitions
概要逻辑如下:
1. ImportSelector的解析在ConfigurationClassParser#processImports中处理在其中this.deferredImportSelectorHandler.handle(..)将DeferredImportSelector放入队列,延后处理。
2. DeferredImportSelector处理逻辑在ConfigurationClassParser#parse中的this.deferredImportSelectorHandler.process()中。
浏览this.deferredImportSelectorHandler.process()代码
DeferredImportSelectorGrouping#getImports的代码如下:
private static class DeferredImportSelectorGrouping {
private final Group group;
private final List<ConfigurationClassParser.DeferredImportSelectorHolder> deferredImports = new ArrayList();
DeferredImportSelectorGrouping(Group group) {
this.group = group;
}
public void add(ConfigurationClassParser.DeferredImportSelectorHolder deferredImport) {
this.deferredImports.add(deferredImport);
}
public Iterable<Entry> getImports() {
Iterator var1 = this.deferredImports.iterator();
while(var1.hasNext()) {
ConfigurationClassParser.DeferredImportSelectorHolder deferredImport = (ConfigurationClassParser.DeferredImportSelectorHolder)var1.next();
this.group.process(deferredImport.getConfigurationClass().getMetadata(), deferredImport.getImportSelector());
}
return this.group.selectImports();
}
这里需要关注的是this.group.process,this.group.selectImports2个方法。
也就是AutoConfigurationImportSelector.AutoConfigurationGroup的process,selectImports就是我们需要关注的核心方法。
逐个分析
process
private static class AutoConfigurationGroup implements Group, BeanClassLoaderAware, BeanFactoryAware, ResourceLoaderAware {
private final Map<String, AnnotationMetadata> entries = new LinkedHashMap();
private final List<AutoConfigurationImportSelector.AutoConfigurationEntry> autoConfigurationEntries = new ArrayList();
private ClassLoader beanClassLoader;
private BeanFactory beanFactory;
private ResourceLoader resourceLoader;
private AutoConfigurationMetadata autoConfigurationMetadata;
private AutoConfigurationGroup() {
}
public void setBeanClassLoader(ClassLoader classLoader) {
this.beanClassLoader = classLoader;
}
public void setBeanFactory(BeanFactory beanFactory) {
this.beanFactory = beanFactory;
}
public void setResourceLoader(ResourceLoader resourceLoader) {
this.resourceLoader = resourceLoader;
}
public void process(AnnotationMetadata annotationMetadata, DeferredImportSelector deferredImportSelector) {
Assert.state(deferredImportSelector instanceof AutoConfiguratio