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*** 的注解,这种注解的作用就是判断该配置类在什么时候能够起作用。

更多教程请参考 flydean的博客

Spring Boot @EnableAutoConfiguration和 @Configuration的区别的更多相关文章

  1. Inspection info: Checks Spring Boot application .properties configuration files. Highlights unresolved and deprecated configuration keys and in

    Cannot resolve class or package ‘jdbc’ less… (Ctrl+F1) Inspection info: Checks Spring Boot applicati ...

  2. Spring Boot @EnableAutoConfiguration解析

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

  3. spring boot EnableAutoConfiguration exclude 无效

    本文链接:https://blog.csdn.net/ID19870510/article/details/79373386 首先讲一下SpringBootApplication注解源码定义为 @Ta ...

  4. 【Spring Boot源码分析】@EnableAutoConfiguration注解(一)@AutoConfigurationImportSelector注解的处理

    Java及Spring Boot新手,首次尝试源码分析,欢迎指正! 一.概述 @EnableAutoConfiguration注解是Spring Boot中配置自动装载的总开关.本文将从@Enable ...

  5. (转)Spring Boot(一)

    (二期)4.springboot的综合讲解 [课程四]springbo...概念.xmind64.5KB [课程四]spring装配方式.xmind0.2MB [课程四预习]spri...解读.xmi ...

  6. [Spring Boot] Spring Boot启动过程源码分析

    关于Spring Boot,已经有很多介绍其如何使用的文章了,本文从源代码(基于Spring-boot 1.5.6)的角度来看看Spring Boot的启动过程到底是怎么样的,为何以往纷繁复杂的配置到 ...

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

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

  8. Spring boot运行原理-自定义自动配置类

    在前面SpringBoot的文章中介绍了SpringBoot的基本配置,今天我们将给大家讲一讲SpringBoot的运行原理,然后根据原理我们自定义一个starter pom. 本章对于后续继续学习S ...

  9. Spring Boot 笔记 (1) - Maven、基本配置、Profile的使用

    一. Spring Boot 简介 开箱即用的一站式 Java EE 解决方案 Spring 技术栈的大整合 核心问题 暂时无法回答 Spring Boot 和 SOA 有什么区别? Spring B ...

随机推荐

  1. Spring Boot 整合视图层技术,application全局配置文件

    目录 Spring Boot 整合视图层技术 Spring Boot 整合jsp Spring Boot 整合freemarker Spring Boot 整合视图层技术 Spring Boot 整合 ...

  2. Xshell连接Centos7

    13:53:10 2019-08-05 一个月暑假开始 学习搭建一个自己的博客 我是用阿里云的服务器搭建自己的博客 先利用XShell连接我的服务器 XShell下载地址:https://www.ne ...

  3. PTA | 1008 数组元素循环右移问题 (20分)

    一个数组A中存有N(N>0)个整数,在不允许使用另外数组的前提下,将每个整数循环向右移M(M>=0)个位置,即将A中的数据由(A0 A1--AN-1)变换为(AN-M -- AN-1 A0 ...

  4. 萌新带你开车上p站(三)

    本文作者:萌新 前情回顾: 萌新带你开车上p站(一) 萌新带你开车上p站(二) 0x08 题目给的提示是和运算符优先级有关 登录后直接看源码 mistake@pwnable:~$ ls flag mi ...

  5. 微信小程序页面通信

    目录 微信小程序页面通信 方式一:通过URL 方式二:通过全局变量 方式三:通过本地存储 方式四:通过路由栈 微信小程序页面通信 方式一:通过URL // A 页面 wx.navigateTo({ u ...

  6. 了解一下mock

    1.mock简介: mock测试就是在测试过程中,对于某些不容易构成或者不容易获取的对象,用一个虚拟的对象来创建以便测试的测试方法,mock是在测试过程中,对于一些不容易构造/获取的对象,创建一个mo ...

  7. CentOS7安装MYCAT中间件

    MYCAT是一个被广泛使用的功能强大的开源的数据库中间件,当然他的理想不仅仅是做一个中间件.这篇文章主要记录MYCAT服务的搭建过程,下篇会继续更新MYCAT的使用配置. 本篇记录将使用CentOS7 ...

  8. AJ学IOS(24)UI之注册案例

    AJ分享,必须精品 先看效果 制作思路 在做这个的时候,首先用stroyboard画出来界面UI,这个很简单,不多说了,然后下一步就是自定义xib做键盘上面的那一栏了,需要自己做xib还有view,详 ...

  9. intellij idea 设置用真机测试android

    android自带的模拟器是不容置疑的慢,genymontion虽然快,但是觉得有点怪的感觉,哈哈,其实这些都不是重点. 之前是用myeclipse开发android的,虽然一直很想用eclipse来 ...

  10. matlab将数据读取和写入txt文档

    原文链接 matlab中打开文件 fid = fopen(文件名,‘打开方式’): 说明:fid用于存储文件句柄值,如果fid>0,这说明文件打开成功. 另外,在这些字符串后添加一个“t”,如‘ ...