通常我们启动一个springboot项目会在启动方法中增加@SpringBootApplicatoin注解,该注解中包含了@EnableAutoConfiguration

@Target(ElementType.TYPE)
@Retention(RetentionPolicy.RUNTIME)
@Documented
@Inherited
@SpringBootConfiguration
@EnableAutoConfiguration
@ComponentScan(excludeFilters={@Filter(type= FilterType.CUSTOM, classes = TypeExcludeFilter.class),@Filter(type= FilterType.CUSTOM, classes = AutoConfigurationExcludeFilter.class) })public @interfaceSpringBootApplication {/*** Exclude specific auto-configuration classes such that they will never be applied.*@returnthe classes to exclude*/@AliasFor(annotation= EnableAutoConfiguration.class)Class<?>[] exclude() default{};/*** Exclude specific auto-configuration class names such that they will never be* applied.*@returnthe class names to exclude*@since1.3.0*/@AliasFor(annotation= EnableAutoConfiguration.class)String[] excludeName()default{};/*** Base packages to scan for annotated components. Use {@link#scanBasePackageClasses}* for a type-safe alternative to String-based package names.*@returnbase packages to scan*@since1.3.0*/@AliasFor(annotation= ComponentScan.class, attribute = "basePackages")String[] scanBasePackages()default{};/*** Type-safe alternative to {@link#scanBasePackages} for specifying the packages to* scan for annotated components. The package of each class specified will be scanned.* <p>* Consider creating a special no-op marker class or interface in each package that* serves no purpose other than being referenced by this attribute.*@returnbase packages to scan*@since1.3.0*/@AliasFor(annotation= ComponentScan.class, attribute = "basePackageClasses")Class<?>[] scanBasePackageClasses() default{};}

那么@EnableAutoConfiguration是如何自动起作用的呢。我们先来看看@EnableAutoConfiguration的定义

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

我们看看EnableAutoConfiguration的注释定义:

Enable auto-configuration of the Spring Application Context, attempting to guess and* configure beans that you are likely to need. Auto-configuration classes are usually* applied based on your classpath and what beans you have defined.

大概的意思是:容器尝试猜测你想配置的bean,然后自动加载。

很欣喜的发现了@EnableAutoConfiguration里面引用了@Import(AutoConfigurationImportSelector.class),直觉看起来像这个AutoConfigurationImportSelector里面引入了我们那些自动配置(数据源、拦截器)的类。

我们来看看AutoConfigurationImportSelector的定义:

public classAutoConfigurationImportSelectorimplementsDeferredImportSelector, BeanClassLoaderAware, ResourceLoaderAware,
BeanFactoryAware, EnvironmentAware, Ordered

原来AutoConfigurationImportSelector类实现了org.springframework.context.annotation.DeferredImportSelector

那么实现了该类的public String[] selectImports(AnnotationMetadata annotationMetadata)后,spring在解析bean的时候,就会自动调用该方法来加载拓展类,也就是selectImports方法返回的名称列表来加载类。

很容易起想到selectImports里面就返回了AutoEnableConfiguration的那些数据源、拦截器配置的类。!

接下来看看selectImports的具体实现:

@OverridepublicString[] selectImports(AnnotationMetadata annotationMetadata) {if (!isEnabled(annotationMetadata)) {returnNO_IMPORTS;}        //从org.springframework.boot.autoconfigure.AutoConfigurationMetadataLoader的loadMetadata加载要自动配置的资源数据
AutoConfigurationMetadata autoConfigurationMetadata =AutoConfigurationMetadataLoader.loadMetadata(this.beanClassLoader);AutoConfigurationEntry autoConfigurationEntry=getAutoConfigurationEntry(autoConfigurationMetadata, annotationMetadata);returnStringUtils.toStringArray(autoConfigurationEntry.getConfigurations());}

看下AutoConfigurationMetadataLoader的源码看,可以看到默认加载的自动配置的路径为:/META-INF/spring-autoconfigure-metadata.properteis。

final classAutoConfigurationMetadataLoader {//默认加载自动配置的文件位置protected static final String PATH = "META-INF/"+ "spring-autoconfigure-metadata.properties";privateAutoConfigurationMetadataLoader() {}public staticAutoConfigurationMetadata loadMetadata(ClassLoader classLoader) {returnloadMetadata(classLoader, PATH);}staticAutoConfigurationMetadata loadMetadata(ClassLoader classLoader, String path) {try{Enumeration<URL> urls = (classLoader != null) ?classLoader.getResources(path): ClassLoader.getSystemResources(path);Properties properties= newProperties();while(urls.hasMoreElements()) {properties.putAll(PropertiesLoaderUtils.loadProperties(newUrlResource(urls.nextElement())));}returnloadMetadata(properties);}catch(IOException ex) {throw newIllegalArgumentException("Unable to load @ConditionalOnClass location [" + path + "]", ex);}}staticAutoConfigurationMetadata loadMetadata(Properties properties) {return newPropertiesAutoConfigurationMetadata(properties);}/*** {@linkAutoConfigurationMetadata} implementation backed by a properties file.*/private static classPropertiesAutoConfigurationMetadataimplementsAutoConfigurationMetadata {private finalProperties properties;PropertiesAutoConfigurationMetadata(Properties properties) {this.properties =properties;}@Overridepublic booleanwasProcessed(String className) {return this.properties.containsKey(className);}@OverridepublicInteger getInteger(String className, String key) {return getInteger(className, key, null);}@OverridepublicInteger getInteger(String className, String key, Integer defaultValue) {String value=get(className, key);return (value != null) ?Integer.valueOf(value) : defaultValue;}@Overridepublic Set<String>getSet(String className, String key) {return getSet(className, key, null);}@Overridepublic Set<String>getSet(String className, String key,Set<String>defaultValue) {String value=get(className, key);return (value != null) ?StringUtils.commaDelimitedListToSet(value): defaultValue;}@OverridepublicString get(String className, String key) {return get(className, key, null);}@OverridepublicString get(String className, String key, String defaultValue) {String value= this.properties.getProperty(className + "." +key);return (value != null) ?value : defaultValue;}}}

可以看到配置的默认加载的配载类有如下,这些类都被@Confiration注解,并且都自动创建了一些@Bean来使用组件的特性,通过这些自动创建的bean来代替我们系统中手动声明bean,达到加快开发效率的效果。

[org.springframework.boot.autoconfigure.admin.SpringApplicationAdminJmxAutoConfiguration, org.springframework.boot.autoconfigure.cache.CacheAutoConfiguration, org.springframework.boot.autoconfigure.context.ConfigurationPropertiesAutoConfiguration, org.springframework.boot.autoconfigure.context.MessageSourceAutoConfiguration, org.springframework.boot.autoconfigure.context.PropertyPlaceholderAutoConfiguration, org.springframework.boot.autoconfigure.http.HttpMessageConvertersAutoConfiguration, org.springframework.boot.autoconfigure.http.codec.CodecsAutoConfiguration, org.springframework.boot.autoconfigure.info.ProjectInfoAutoConfiguration, org.springframework.boot.autoconfigure.jackson.JacksonAutoConfiguration, org.springframework.boot.autoconfigure.jmx.JmxAutoConfiguration, org.springframework.boot.autoconfigure.task.TaskExecutionAutoConfiguration, org.springframework.boot.autoconfigure.task.TaskSchedulingAutoConfiguration, org.springframework.boot.autoconfigure.validation.ValidationAutoConfiguration, org.springframework.boot.autoconfigure.web.client.RestTemplateAutoConfiguration, org.springframework.boot.autoconfigure.web.embedded.EmbeddedWebServerFactoryCustomizerAutoConfiguration, org.springframework.boot.autoconfigure.web.servlet.DispatcherServletAutoConfiguration, org.springframework.boot.autoconfigure.web.servlet.ServletWebServerFactoryAutoConfiguration, org.springframework.boot.autoconfigure.web.servlet.error.ErrorMvcAutoConfiguration, org.springframework.boot.autoconfigure.web.servlet.HttpEncodingAutoConfiguration, org.springframework.boot.autoconfigure.web.servlet.MultipartAutoConfiguration, org.springframework.boot.autoconfigure.web.servlet.WebMvcAutoConfiguration, org.springframework.boot.autoconfigure.websocket.servlet.WebSocketServletAutoConfiguration]

至此,springboot自动加载配置的原理也分析完毕。

转载于:https://www.cnblogs.com/swave/p/10966697.html

springboot的@EnableAutoConfiguration起作用的原理相关推荐

  1. 《Spring源码深度解析 郝佳 第2版》SpringBoot体系分析、Starter的原理

    往期博客 <Spring源码深度解析 郝佳 第2版>容器的基本实现与XML文件的加载 <Spring源码深度解析 郝佳 第2版>XML标签的解析 <Spring源码深度解 ...

  2. Spring boot热部署的作用和原理

    Spring boot热部署的作用和原理 前言 一.Spring boot热部署的作用 1.什么是SpringBoot热部署 2.什么项目重启 3.什么静态文件 4.如何使用Spring boot热部 ...

  3. volatile关键字的作用、原理

    在只有双重检查锁,没有volatile的懒加载单例模式中,由于指令重排序的问题,我确实不会拿到两个不同的单例了,但我会拿到"半个"单例. 而发挥神奇作用的volatile,可以当之 ...

  4. Bundler 的作用及原理

    Bundler 的作用及原理 翻译 · yesmeck · Created at one year ago · Last by teacafe2000 Replied at one year ago  ...

  5. JAVA基础加强(张孝祥)_类加载器、分析代理类的作用与原理及AOP概念、分析JVM动态生成的类、实现类似Spring的可配置的AOP框架...

    1.类加载器 ·简要介绍什么是类加载器,和类加载器的作用 ·Java虚拟机中可以安装多个类加载器,系统默认三个主要类加载器,每个类负责加载特定位置的类:BootStrap,ExtClassLoader ...

  6. Batch Normalization的作用及原理

    目录 声明 BN是什么[1] 为什么提出BN[1, 2] BN的作用及原理 加速训练,提高收敛速度[1] 缓解梯度消失(梯度爆炸)[3] 缓解过拟合[4] 其他相关问题 BN和激活函数的顺序问题[5] ...

  7. Springboot默认加载application.yml原理

    Springboot默认加载application.yml原理以及扩展 SpringApplication.run(-)默认会加载classpath下的application.yml或applicat ...

  8. 【原创】uC/OS 中LES BX,DWORD PTR DS:_OSTCBCur的作用及原理

    1 LES BX, DWORD PTR DS:_OSTCBCur ;OSTCBCur->OSTCBStkPtr = SS:SP!!! 2 MOV ES:[BX+2], SS ;将当前SS(栈的基 ...

  9. python super()方法的作用_详解python的super()的作用和原理

    Python中对象方法的定义很怪异,第一个参数一般都命名为self(相当于其它语言的this),用于传递对象本身,而在调用的时候则不必显式传递,系统会自动传递.uz0免费资源网 今天我们介绍的主角是s ...

最新文章

  1. Maya人物角色行走动画制作视频教程
  2. Mass对象类型介绍
  3. python伪装浏览器什么意思_用python2和python3伪装浏览器爬取网页
  4. 访问被拒绝:“microsoft.web.ui.webcontrols”的解决办法
  5. python fsolve说明_Python fsolve()抱怨形状.为什么?
  6. 简约而不简单的 Django 新手图文教程
  7. 关于TCP的粘包问题
  8. Python笔记-房贷计算(本息和本金,每月还利息和每月还本金)及作图对比
  9. linux c 密码 星号,Linux C : 登录密码星号 * 显示,包含能回退 backspace
  10. Atitit.在线充值功能的设计
  11. 计算机高程知识点,数字测图原理与方法知识点
  12. 欧瑞变频器800参数设置_常见品牌变频器修改功率方法大全
  13. 读书笔记—产品型社群:互联网思维的本质
  14. 函数的支集、支撑集、support、supp
  15. 武汉Java程序员工资是否还会增长?工资为什么那么高?
  16. 学llinux的资料
  17. 红米k60和k50至尊版参数对比 Redmi k60和k50至尊版哪个好
  18. 【HTML】【休闲益智】真相?真香?只有一个!看看谁是大馋虫 or 贪吃鬼(找出真正吃了月饼的人
  19. python怎么判断等于_python中怎么判断不等于
  20. 这几种神级性能优化手段,你用过几个?

热门文章

  1. 数组转集合集合转数组 split方法
  2. nginx authorization 丢失_婚礼影像丢失 损失如何弥补?_政务_澎湃新闻
  3. java主函数_《左手 Java 右手 Python 》之 Java 的安装与初识(1)
  4. eclipse修改git账号信息
  5. centos7 dotnet command not found
  6. Idea springboot应用,启动报错:org.yaml.snakeyaml.error.YAMLException: java.nio.charset.MalformedInputExcept
  7. HashMap在Jdk1.7和1.8中的实现
  8. Android开发笔记(五十五)手机设备基本操作
  9. Android开发笔记(二十九)使用SharedPreferences存取数据
  10. Android 动态移动控件实现