@EnableAutoConfiguration和@ImportAutoConfiguration的区别 您所在的位置:网站首页 disable和enabled的区别 @EnableAutoConfiguration和@ImportAutoConfiguration的区别

@EnableAutoConfiguration和@ImportAutoConfiguration的区别

2023-07-05 01:36| 来源: 网络整理| 查看: 265

@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 configurations = getCandidateConfigurations(annotationMetadata, attributes); // 去除重复的自动配置类 configurations = removeDuplicates(configurations); Set 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 getCandidateConfigurations(AnnotationMetadata metadata, AnnotationAttributes attributes) { List candidates = new ArrayList(); // 获取所有的@ImportAutoConfiguration注解 Map annotations = getAnnotations(metadata); // 重点关注一下 collectCandidateConfigurations方法 annotations.forEach((source, sourceAnnotations) -> collectCandidateConfigurations( source, sourceAnnotations, candidates)); return candidates; } collectCandidateConfigurations方法 private void collectCandidateConfigurations(Class source, List annotations, List candidates) { for (Annotation annotation : annotations) { // 跟进 getConfigurationsForAnnotation 方法 candidates.addAll(getConfigurationsForAnnotation(source, annotation)); } } getConfigurationsForAnnotation方法 private Collection 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修饰的类), 试着随便找一个 在这里插入图片描述 经过上面的分析, 大家肯定已经大体对两个注解的处理流程有了一定的认识, 下面我们来总结一下! (如果大家觉得看完对自己有那么一丁点的帮助, 帮我点点赞吧, 感谢感谢) 总结一下

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

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

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

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



【本文地址】

公司简介

联系我们

今日新闻

    推荐新闻

    专题文章
      CopyRight 2018-2019 实验室设备网 版权所有