聊聊SpringBoot中的@EnableAutoConfiguration注解

本文详细探讨了SpringBoot中的@EnableAutoConfiguration注解的工作原理,从核心方法AutoConfigurationImportSelector入手,分析了getAutoConfigurationMetadata()和getAutoConfigurationEntry()等关键步骤,揭示了自动配置的加载、排序和过滤逻辑。同时,文章提到了自定义配置如何覆盖自动装配的条件,并对整个处理流程进行了总结。
摘要由CSDN通过智能技术生成

引言

@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
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值