Spring Boot @EnableAutoConfiguration和 @Configuration的区别
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的区别相关推荐
- Spring 和 Spring Boot 之间到底有啥区别?
概述 对于Spring和SpringBoot到底有什么区别,我听到了很多答案,刚开始迈入学习SpringBoot的我当时也是一头雾水,随着经验的积累.我慢慢理解了这两个框架到底有什么区别,相信对于用了 ...
- spring揭秘_被问到了! Spring 和 Spring Boot 之间到底有啥区别?
相信很多小伙伴和我一样,常用Spring 和Spring Boot 但是就是没有研究二者之间到底有什么区别? 今天就来大揭秘 ↓ 概述 对于 Spring和 SpringBoot到底有什么区别,我听到 ...
- Spring Boot @EnableAutoConfiguration解析
刚做后端开发的时候,最早接触的是基础的spring,为了引用二方包提供bean,还需要在xml中增加对应的包<context:component-scan base-package=" ...
- Spring Boot——@ConfigurationProperties与@Value的区别
引言 Spring Boot从配置文件中取值的方式有两种,一种是批量注入@ConfigurationProperties,另一种是单独注入@Value. 它们之间除了批量与单独取值的区别之外,还存在着 ...
- Spring Boot 2.X系列教程:七天从无到有掌握Spring Boot-持续更新
文章目录 简介 Spring Boot的基本操作 Spring Boot的构建和部署 Spring Boot工具 Spring Boot的测试 Spring Boot中使用JPA Spring Boo ...
- Spring、Spring Boot和TestNG测试指南 - 测试@Configuration
Github地址 在Spring引入Java Config机制之后,我们会越来越多的使用@Configuration来注册Bean,并且Spring Boot更广泛地使用了这一机制,其提供的大量Aut ...
- Spring Boot启动过程源码分析--转
https://blog.csdn.net/dm_vincent/article/details/76735888 关于Spring Boot,已经有很多介绍其如何使用的文章了,本文从源代码(基于Sp ...
- Spring Boot - 自动配置实现原理
文章目录 Pre @SpringBootApplication 注解 @ComponentScan 注解 @SpringBootConfiguration 注解 @EnableAutoConfigur ...
- Spring Boot 到底是怎么做到自动配置的?
作者:祖大帅 juejin.im/post/5b679fbc5188251aad213110 SpringBoot的故事从一个面试题开始 Spring Boot.Spring MVC 和 Spring ...
最新文章
- lisp 批量文字求差值_Python 超简单 提取音乐高潮(附批量提取)
- 数据库备份DBS提供异常任务自助修复
- 第4步 tomcat配置中文字符集 启动Tomcat 网页乱码
- JVM调优 dump文件怎么生成和分析
- H3C 以太网集线器
- 团队作业7——Beta版本冲刺计划及安排
- 上传声音 微信小程序_SpringBoot开发案例之微信小程序录音上传
- 详解协方差与协方差矩阵计算
- Anaconda中出现No module named cv2
- Linux下,查看USB设备信息
- MySQL Sleep进程
- 【PLY】Lex和Yacc简单示例
- 浪潮服务器风扇转速调节(已解决)
- 伺服驱动器方案,迈信ep100 成熟方案STM32源码
- 优酷KUX视频转换MP4工具,纯个人向分享
- 泛微oa流程表单之取值弹窗
- java当前日期星期几_java获取当前日期是星期几
- 在无处落脚的大海,你就是我的岛屿
- 抽纸(面巾纸),卫生纸,湿巾纸,厨房用纸,
- eclipse的小知识点
热门文章
- 【玩转cocos2d-x之二十六】数据结构CCDictionary
- Shell程序设计 | 基本语法 :变量、I/O、算术运算、条件判断、流程控制、函数
- 第32讲:实时处理利器 mitmproxy 的使用
- 看完这篇文章,我奶奶都懂了https的原理
- Linux(CentOS)中常用软件安装,使用及异常——XManager, 中文支持,JDK
- TCP协议通讯流程(三次握手及四次挥手)
- 【大会】没有什么比把码率降低更爽的了
- x265与SVT-HEVC现已合二为一
- 北京大学数字视频编解码技术国家工程实验室开源AVS2高清实时编码器
- URG与PSH的联系和区别