@EnableAutoConfiguration和@ImportAutoConfiguration的区别

@EnableAutoConfiguration和@ImportAutoConfiguration注解的区别

首先, 说明一下, 我是在研究SpringBoot测试相关内容, 在@DataJpaTest注解上发现的这个@ImportAutoConfiguration注解, 本着不懂就学的态度, 顺便研究一下!

@EnableAutoConfiguration注解大家都知道, 属于启动类注解@SpringBootApplication中的注解

1. 先比较一下两个注解

在这里插入图片描述

两点不同

  • @EnableAutoConfiguration多了一个@AutoConfigurationPackage注解, 这个@AutoConfigurationPackage是用来存储自动扫描的包信息, 给后续的Jpa等扫包使用

  • @Import引入的类不同, 这是主要的一点, 我们着重来看一下

@Import注解的作用

@Import注解的作用是为了单独引入配置类, 可以是外部配置也可以是自定义的配置, 关于他的更多细节, 暂时先不展开了, 如果感兴趣, 欢迎评论区留言.

2. 重点研究一下这两个类

AutoConfigurationImportSelector类

selectImports方法
@Override
public String[] selectImports(AnnotationMetadata annotationMetadata) {
    // 如果不开启自动配置, 返回空
    if (!isEnabled(annotationMetadata)) {
        return NO_IMPORTS;
    }
    AutoConfigurationMetadata autoConfigurationMetadata = AutoConfigurationMetadataLoader
        .loadMetadata(this.beanClassLoader);
    AnnotationAttributes attributes = getAttributes(annotationMetadata);
    // 从META-INF/spring.factories文件中获取自动配置类
    List<String> configurations = getCandidateConfigurations(annotationMetadata,
                                                             attributes);
    // 去除重复的自动配置类
    configurations = removeDuplicates(configurations);
    Set<String> exclusions = getExclusions(annotationMetadata, attributes);
    // 排除手动设置的需要去除的配置类
    checkExcludedClasses(configurations, exclusions);
    configurations.removeAll(exclusions);
    // 利用OnClassCondition类对依赖的类进行校验
    configurations = filter(configurations, autoConfigurationMetadata);
    // 发送自动配置导入事件
    fireAutoConfigurationImportEvents(configurations, exclusions);
    return StringUtils.toStringArray(configurations);
}

再看ImportAutoConfigurationImportSelector

这个类继承自上面的AutoConfigurationImportSelector, 那我们重点关注一下这个类重写的一些方法

在这里插入图片描述

getCandidateConfigurations方法
@Override
protected List<String> getCandidateConfigurations(AnnotationMetadata metadata,
                                                  AnnotationAttributes attributes) {
    List<String> candidates = new ArrayList<>();
    // 获取所有的@ImportAutoConfiguration注解
    Map<Class<?>, List<Annotation>> annotations = getAnnotations(metadata);
    // 重点关注一下 collectCandidateConfigurations方法
    annotations.forEach((source, sourceAnnotations) -> collectCandidateConfigurations(
        source, sourceAnnotations, candidates));
    return candidates;
}
collectCandidateConfigurations方法
private void collectCandidateConfigurations(Class<?> source,
                                            List<Annotation> annotations, List<String> candidates) {
    for (Annotation annotation : annotations) {
        // 跟进 getConfigurationsForAnnotation 方法
        candidates.addAll(getConfigurationsForAnnotation(source, annotation));
    }
}
getConfigurationsForAnnotation方法
private Collection<String> getConfigurationsForAnnotation(Class<?> source,
                                                          Annotation annotation) {
    // 获取@ImportAutoConfiguration中的classes属性
    String[] classes = (String[]) AnnotationUtils
        .getAnnotationAttributes(annotation, true).get("classes");
    // 如果classes不为空则返回
    if (classes.length > 0) {
        return Arrays.asList(classes);
    }
    // 否则获取底层类在META-INF/spring.factories文件中对应的配置类
    return loadFactoryNames(source);
}
结合@DataJpaTest看一下

在这里插入图片描述

@ImportAutoConfiguration注解执行上述ImportAutoConfigurationImportSelector解析流程

  • 获取所有的@ImportAutoConfiguration注解, 这里可不止是他自己啊, 还有一堆AutoConfiguration开头的注解, 随便选一个看一下

    TIPS:

    这里也间接说明以AutoConfiguration开头的注解功能上都是通过@ImportAutoConfiguration实现的

在这里插入图片描述

  • 但是所有的@ImportAutoConfiguration中classes属性都是空的, 这种情况下就会从META-INF/spring.factories获取底层类为key的配置类(底层类指的就是@ImportAutoConfiguration修饰的类), 试着随便找一个
    在这里插入图片描述
    经过上面的分析, 大家肯定已经大体对两个注解的处理流程有了一定的认识, 下面我们来总结一下! (如果大家觉得看完对自己有那么一丁点的帮助, 帮我点点赞吧, 感谢感谢)

总结一下

  1. @EnableAutoConfiguration是加载所有的自动配置类, 这其中包含了缓存, JPA等功能的自动配置类

    org.springframework.boot.autoconfigure.EnableAutoConfiguration为key的自动配置类
    在这里插入图片描述

  2. @ImportAutoConfiguration加载自定义属性classes中的配置类集合或者某一独立功能的自动配置类集合(如AutoConfigureCache)

  3. 因此@ImportAutoConfiguration的相比较@EnableAutoConfiguration而言, 更加灵活, 并且实现了对自动配置的范围定制

  • 1
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值