Spring Boot @EnableAutoConfiguration和
@Configuration的区别

在Spring Boot中,我们会使用@SpringBootApplication来开启Spring Boot程序。在之前的文章中我们讲到了@SpringBootApplication相当于@EnableAutoConfiguration,@ComponentScan,@Configuration三者的集合。

其中@Configuration用在类上面,表明这个是个配置类,如下所示:

@Configuration
public class MySQLAutoconfiguration {...
}

而@EnableAutoConfiguration则是开启Spring Boot的自动配置功能。什么是自动配置功能呢?简单点说就是Spring Boot根据依赖中的jar包,自动选择实例化某些配置。

接下来我们看一下@EnableAutoConfiguration是怎么工作的。

先看一下@EnableAutoConfiguration的定义:

@Target(ElementType.TYPE)
@Retention(RetentionPolicy.RUNTIME)
@Documented
@Inherited
@AutoConfigurationPackage
@Import(AutoConfigurationImportSelector.class)
public @interface EnableAutoConfiguration {String ENABLED_OVERRIDE_PROPERTY = "spring.boot.enableautoconfiguration";/*** Exclude specific auto-configuration classes such that they will never be applied.* @return the classes to exclude*/Class<?>[] exclude() default {};/*** Exclude specific auto-configuration class names such that they will never be* applied.* @return the class names to exclude* @since 1.3.0*/String[] excludeName() default {};}

注意这一行: @Import(AutoConfigurationImportSelector.class)

AutoConfigurationImportSelector实现了ImportSelector接口,并会在实例化时调用selectImports。下面是其方法:

 public String[] selectImports(AnnotationMetadata annotationMetadata) {if (!isEnabled(annotationMetadata)) {return NO_IMPORTS;}AutoConfigurationMetadata autoConfigurationMetadata = AutoConfigurationMetadataLoader.loadMetadata(this.beanClassLoader);AutoConfigurationEntry autoConfigurationEntry = getAutoConfigurationEntry(autoConfigurationMetadata,annotationMetadata);return StringUtils.toStringArray(autoConfigurationEntry.getConfigurations());}

这个方法中的getCandidateConfigurations会从类加载器中查找所有的META-INF/spring.factories,并加载其中实现了@EnableAutoConfiguration的类。 有兴趣的朋友可以具体研究一下这个方法的实现。

private static Map<String, List<String>> loadSpringFactories(@Nullable ClassLoader classLoader) {MultiValueMap<String, String> result = cache.get(classLoader);if (result != null) {return result;}try {Enumeration<URL> urls = (classLoader != null ?classLoader.getResources(FACTORIES_RESOURCE_LOCATION) :ClassLoader.getSystemResources(FACTORIES_RESOURCE_LOCATION));result = new LinkedMultiValueMap<>();while (urls.hasMoreElements()) {URL url = urls.nextElement();UrlResource resource = new UrlResource(url);Properties properties = PropertiesLoaderUtils.loadProperties(resource);for (Map.Entry<?, ?> entry : properties.entrySet()) {String factoryTypeName = ((String) entry.getKey()).trim();for (String factoryImplementationName : StringUtils.commaDelimitedListToStringArray((String) entry.getValue())) {result.add(factoryTypeName, factoryImplementationName.trim());}}}cache.put(classLoader, result);return result;}catch (IOException ex) {throw new IllegalArgumentException("Unable to load factories from location [" +FACTORIES_RESOURCE_LOCATION + "]", ex);}}

我们再看一下spring-boot-autoconfigure-2.2.2.RELEASE.jar中的META-INF/spring.factories。

spring.factories里面的内容是key=value形式的,我们重点关注一下EnableAutoConfiguration:

# Auto Configure
org.springframework.boot.autoconfigure.EnableAutoConfiguration=\
org.springframework.boot.autoconfigure.admin.SpringApplicationAdminJmxAutoConfiguration,\
org.springframework.boot.autoconfigure.aop.AopAutoConfiguration,\
org.springframework.boot.autoconfigure.amqp.RabbitAutoConfiguration,\
org.springframework.boot.autoconfigure.batch.BatchAutoConfiguration,\
org.springframework.boot.autoconfigure.cache.CacheAutoConfiguration,\
org.springframework.boot.autoconfigure.cassandra.CassandraAutoConfiguration,\
org.springframework.boot.autoconfigure.cloud.CloudServiceConnectorsAutoConfiguration,\
org.springframework.boot.autoconfigure.context.ConfigurationPropertiesAutoConfiguration,\
...

这里只列出了一部分内容,根据上面的代码, 所有的EnableAutoConfiguration的实现都会被自动加载。这就是自动加载的原理了。

如果我们仔细去看具体的实现:

@Configuration(proxyBeanMethods = false)
@AutoConfigureAfter(JmxAutoConfiguration.class)
@ConditionalOnProperty(prefix = "spring.application.admin", value = "enabled", havingValue = "true",matchIfMissing = false)
public class SpringApplicationAdminJmxAutoConfiguration {

可以看到里面使用了很多@Conditional*** 的注解,这种注解的作用就是判断该配置类在什么时候能够起作用。

更多精彩内容且看:

  • 区块链从入门到放弃系列教程-涵盖密码学,超级账本,以太坊,Libra,比特币等持续更新
  • Spring Boot 2.X系列教程:七天从无到有掌握Spring Boot-持续更新
  • Spring 5.X系列教程:满足你对Spring5的一切想象-持续更新
  • java程序员从小工到专家成神之路(2020版)-持续更新中,附详细文章教程

更多教程请参考 flydean的博客

Spring Boot @EnableAutoConfiguration和 @Configuration的区别相关推荐

  1. Spring 和 Spring Boot 之间到底有啥区别?

    概述 对于Spring和SpringBoot到底有什么区别,我听到了很多答案,刚开始迈入学习SpringBoot的我当时也是一头雾水,随着经验的积累.我慢慢理解了这两个框架到底有什么区别,相信对于用了 ...

  2. spring揭秘_被问到了! Spring 和 Spring Boot 之间到底有啥区别?

    相信很多小伙伴和我一样,常用Spring 和Spring Boot 但是就是没有研究二者之间到底有什么区别? 今天就来大揭秘 ↓ 概述 对于 Spring和 SpringBoot到底有什么区别,我听到 ...

  3. Spring Boot @EnableAutoConfiguration解析

    刚做后端开发的时候,最早接触的是基础的spring,为了引用二方包提供bean,还需要在xml中增加对应的包<context:component-scan base-package=" ...

  4. Spring Boot——@ConfigurationProperties与@Value的区别

    引言 Spring Boot从配置文件中取值的方式有两种,一种是批量注入@ConfigurationProperties,另一种是单独注入@Value. 它们之间除了批量与单独取值的区别之外,还存在着 ...

  5. Spring Boot 2.X系列教程:七天从无到有掌握Spring Boot-持续更新

    文章目录 简介 Spring Boot的基本操作 Spring Boot的构建和部署 Spring Boot工具 Spring Boot的测试 Spring Boot中使用JPA Spring Boo ...

  6. Spring、Spring Boot和TestNG测试指南 - 测试@Configuration

    Github地址 在Spring引入Java Config机制之后,我们会越来越多的使用@Configuration来注册Bean,并且Spring Boot更广泛地使用了这一机制,其提供的大量Aut ...

  7. Spring Boot启动过程源码分析--转

    https://blog.csdn.net/dm_vincent/article/details/76735888 关于Spring Boot,已经有很多介绍其如何使用的文章了,本文从源代码(基于Sp ...

  8. Spring Boot - 自动配置实现原理

    文章目录 Pre @SpringBootApplication 注解 @ComponentScan 注解 @SpringBootConfiguration 注解 @EnableAutoConfigur ...

  9. Spring Boot 到底是怎么做到自动配置的?

    作者:祖大帅 juejin.im/post/5b679fbc5188251aad213110 SpringBoot的故事从一个面试题开始 Spring Boot.Spring MVC 和 Spring ...

最新文章

  1. lisp 批量文字求差值_Python 超简单 提取音乐高潮(附批量提取)
  2. 数据库备份DBS提供异常任务自助修复
  3. 第4步 tomcat配置中文字符集 启动Tomcat  网页乱码
  4. JVM调优 dump文件怎么生成和分析
  5. H3C 以太网集线器
  6. 团队作业7——Beta版本冲刺计划及安排
  7. 上传声音 微信小程序_SpringBoot开发案例之微信小程序录音上传
  8. 详解协方差与协方差矩阵计算
  9. Anaconda中出现No module named cv2
  10. Linux下,查看USB设备信息
  11. MySQL Sleep进程
  12. 【PLY】Lex和Yacc简单示例
  13. 浪潮服务器风扇转速调节(已解决)
  14. 伺服驱动器方案,迈信ep100 成熟方案STM32源码
  15. 优酷KUX视频转换MP4工具,纯个人向分享
  16. 泛微oa流程表单之取值弹窗
  17. java当前日期星期几_java获取当前日期是星期几
  18. 在无处落脚的大海,你就是我的岛屿
  19. 抽纸(面巾纸),卫生纸,湿巾纸,厨房用纸,
  20. eclipse的小知识点

热门文章

  1. 【玩转cocos2d-x之二十六】数据结构CCDictionary
  2. Shell程序设计 | 基本语法 :变量、I/O、算术运算、条件判断、流程控制、函数
  3. 第32讲:实时处理利器 mitmproxy 的使用
  4. 看完这篇文章,我奶奶都懂了https的原理
  5. Linux(CentOS)中常用软件安装,使用及异常——XManager, 中文支持,JDK
  6. TCP协议通讯流程(三次握手及四次挥手)
  7. 【大会】没有什么比把码率降低更爽的了
  8. x265与SVT-HEVC现已合二为一
  9. 北京大学数字视频编解码技术国家工程实验室开源AVS2高清实时编码器
  10. URG与PSH的联系和区别