一、写在前面

随着时间的迁移Spring Boot 越来越多的出现在Java 后端程序员的视野中,Spring Boot 之所以会那么流行,很大的一个原因是自身集成了很多的Bean,简化了传统Sring 项目琐碎的文件配置。

这些自动配置的Bean 在入口类启动的时候完成注入,并由Spring 的IoC 容器管理。所以在使用某些Bean的时候,不需要再由我们自动配置。下面我们就通过源码的方式来看看Spring Boot 是如何实现自动配置的。

二、查看自动配置的Bean

我们可以在Spring Boot 项目的配置文件(application.propertiesapplication.yml)中设置一个属性debug=true,设置完成后再启动Spring Boot 的入口类,就会在控制台输出有哪些Bean 已经完成了自动配置。

简单的截了一些如下图:

三、自动配置的原理分析

1.我们从入口类开始分析,我们都知道Spring Boot 项目一般会有一个入口类,这个入口类有一个很重要的特征就是加上了@SpringBootApplication注解。

@SpringBootApplication 是一个组合注解,如下:

@Target(ElementType.TYPE)
@Retention(RetentionPolicy.RUNTIME)
@Documented
@Inherited
@SpringBootConfiguration
@EnableAutoConfiguration
@ComponentScan

其中有一个重要的注解@EnableAutoConfiguration,这个注解的作用就是用于启用Spring Boot 的自动配置。

2.接着具体查看@EnableAutoConfiguration,其实它也是一个组合注解,如下:

@SuppressWarnings("deprecation")
@Target(ElementType.TYPE)
@Retention(RetentionPolicy.RUNTIME)
@Documented
@Inherited
@AutoConfigurationPackage
@Import(EnableAutoConfigurationImportSelector.class)

有一个注解@Import(EnableAutoConfigurationImportSelector.class),在这个注解中有一个导入自动配置的选择器,用于导入自动配置的Bean。

下面就来分析这个EnableAutoConfigurationImportSelector都做了什么。

3.EnableAutoConfigurationImportSelector类继承自AutoConfigurationImportSelector,在这个类中只有一个方法,用于判断是否启动了自动配置。

@Deprecated
public class EnableAutoConfigurationImportSelectorextends AutoConfigurationImportSelector {@Overrideprotected boolean isEnabled(AnnotationMetadata metadata) {if (getClass().equals(EnableAutoConfigurationImportSelector.class)) {return getEnvironment().getProperty(EnableAutoConfiguration.ENABLED_OVERRIDE_PROPERTY, Boolean.class,true);}return true;}}

那么我们就来看看它的父类AutoConfigurationImportSelector

4.在AutoConfigurationImportSelector类中有一个selectImports()方法,如下:

    @Overridepublic String[] selectImports(AnnotationMetadata annotationMetadata) {if (!isEnabled(annotationMetadata)) {return NO_IMPORTS;}try {AutoConfigurationMetadata autoConfigurationMetadata = AutoConfigurationMetadataLoader.loadMetadata(this.beanClassLoader);AnnotationAttributes attributes = getAttributes(annotationMetadata);// 用于获取自动配置的相关信息List<String> configurations = getCandidateConfigurations(annotationMetadata,attributes);configurations = removeDuplicates(configurations);configurations = sort(configurations, autoConfigurationMetadata);/*** 获得移除的自动配置信息* 如果我们不想让Spring Boot 自动配置一些Bean, 我们可以使用在入口类的注解中使用exclude 声明* 比如:@SpringBootApplication(exclude = {DispatcherServlet.class})*/Set<String> exclusions = getExclusions(annotationMetadata, attributes);checkExcludedClasses(configurations, exclusions);configurations.removeAll(exclusions);configurations = filter(configurations, autoConfigurationMetadata);fireAutoConfigurationImportEvents(configurations, exclusions);return configurations.toArray(new String[configurations.size()]);}catch (IOException ex) {throw new IllegalStateException(ex);}}

我们主要查看上面方法中的getCandidateConfigurations(annotationMetadata, attributes)方法,

    protected List<String> getCandidateConfigurations(AnnotationMetadata metadata,AnnotationAttributes attributes) {// 调用SpringFactoriesLoader 的loadFactoryNames() 方法,返回从类路径下获得自动配置相关的信息List<String> configurations = SpringFactoriesLoader.loadFactoryNames(getSpringFactoriesLoaderFactoryClass(), getBeanClassLoader());// 判断自动配置的信息是否为空,为空抛出异常,第二个参数为抛出的异常信息Assert.notEmpty(configurations,"No auto configuration classes found in META-INF/spring.factories. If you "+ "are using a custom packaging, make sure that file is correct.");return configurations;}

下面接着查看loadFactoryNames()方法,

    public static List<String> loadFactoryNames(Class<?> factoryClass, ClassLoader classLoader) {//  factoryClass = EnableAutoConfiguration.class,可以通过上一步查看String factoryClassName = factoryClass.getName();try {/*** FACTORIES_RESOURCE_LOCATION 是一个编译器期量值为:"META-INF/spring.factories"* 用于获得所有jar 包类路径下的META-INF下的spring.factories 文件的URL*/Enumeration<URL> urls = (classLoader != null ? classLoader.getResources(FACTORIES_RESOURCE_LOCATION) :ClassLoader.getSystemResources(FACTORIES_RESOURCE_LOCATION));List<String> result = new ArrayList<String>();while (urls.hasMoreElements()) {URL url = urls.nextElement();// 将扫面到文件中的内容包装成一个Properties 对象Properties properties = PropertiesLoaderUtils.loadProperties(new UrlResource(url));/*** 获取EnableAutoConfiguration 类名在properties 中的值* 这些值对应的Bean 就是要添加到Spring 容器中的自动配置类*/String factoryClassNames = properties.getProperty(factoryClassName);result.addAll(Arrays.asList(StringUtils.commaDelimitedListToStringArray(factoryClassNames)));}return result;}catch (IOException ex) {throw new IllegalArgumentException("Unable to load [" + factoryClass.getName() +"] factories from location [" + FACTORIES_RESOURCE_LOCATION + "]", ex);}}

到这里就可知道Spring Boot 是如何实现自动配置的了,Spring Boot 会扫描到类路径下的META-INF/spring.factories配置文件,把EnableAutoConfiguration对应的的Bean值添加到容器中。

5.接着我们就来看一下类路径下META-INF/spring.factories配置文件,其中EnableAutoConfiguration对应的值都是有哪些。

下面是spring.factories配置文件中EnableAutoConfiguration对应的值,为了显示的效果在这里只贴出一部分。我们可以发现一个规律,这些值一般都是以×××AutoConfiguration命名,每一个×××AutoConfiguration 都作为容器中的一个组件,被添加到IoC 容器中,从而实现Spring Boot 的自动配置。


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.CloudAutoConfiguration,\

四、总结

这篇博文简单的分析了Spring Boot 自动配置的原理,给大家提供一个参考的方向,关于其中的一些具体细节,大家可以自己查看底层的源码进行了解,希望本篇博文能够为你提供帮助。

Spring Boot自动配置原理分析相关推荐

  1. Spring Boot自动配置原理、实战

    Spring Boot自动配置原理 Spring Boot的自动配置注解是@EnableAutoConfiguration, 从上面的@Import的类可以找到下面自动加载自动配置的映射. org.s ...

  2. 芋道 Spring Boot 自动配置原理

    转载自  芋道 Spring Boot 自动配置原理 1. 概述 友情提示:因为本文是分享 Spring Boot 自动配置的原理,所以需要胖友有使用过 Spring Boot 的经验.如果还没使用过 ...

  3. 学习第三篇:【SpringBoot-Labs】芋道 Spring Boot 自动配置原理

    本周(8.21-8.27)将学习芋道 Spring Boot的以下文章: 8.21: 快速入门 8.22:Spring Boot 自动配置原理 .Jar 启动原理 8.23:调试环境. 热部署入门.消 ...

  4. Spring Boot自动配置原理

    要了解Spring Boot的自动配置首先我需要先了解Spring Boot的两个机制,一个是配置文件如何进入到系统变成属性,二是如何将这些属性加入到容器中. 首先我们需要有一个组件,这个组件中的属性 ...

  5. 【Spring Boot实战】源码解析Spring Boot自动配置原理

    一.简介 Spring致力于让Java开发更简单,SpringBoot致力于让使用Spring进行Java开发更简单,SpringCloud致力于基于SpringBoot构建微服务生态圈,让微服务开发 ...

  6. Spring Boot概述与入门特点配置方式注入方式yim配置文件与多文件配置Spring Boot自动配置原理lombok应用

    1. Spring Boot概述 Spring Boot是Spring项目中的一个子工程,与我们所熟知的Spring-framework 同属于spring的产品: 首页Spring Boot简介可以 ...

  7. Spring Boot 自动配置原理

    自动配置原理 配置文件到底能写什么?怎么写?自动配置原理: 参考:https://docs.spring.io/spring-boot/docs/1.5.9.RELEASE/reference/htm ...

  8. Q2 Spring Boot自动配置原理(ok)

    SpringBoot中为什么执行个SpringApplication.run 方法,就可以将classpath下的那么多类注册进IoC容器呢? 我们通过一个例子来看看: @SpringBootAppl ...

  9. Spring Boot 自动配置原理再探

    看了狂神和雷神,我觉得这个自动配置的原理,就是一个属性找值的过程.(即标注了EnableAutoConfiguration注解的类找properties的过程) 第一点:properties从 MET ...

最新文章

  1. 轮播切换_javascript基础(一)——轮播图
  2. 『全球化产品』应该要避开的几个坑
  3. 循序渐进PYTHON3(十三) --4-- DJANGO之CSRF使用
  4. 3 天撸了个数据中台出来,我飘了~
  5. 内网(局域网)中共享文件
  6. SGU 210 Acdream 1227 Beloved Sons KM
  7. 天首发展,音飞储存要起飞
  8. oracle 11g安装自己理解
  9. 【51单片机】通过定时器中断 在8位数码管显示时间
  10. linux 改变用户组、文件拥有者、文件属性
  11. 学生管理系统IPO图_一篇文章带你走进数据流图的世界
  12. 一,SpringBoot——安装spring boot CLI
  13. 没有mysql不能设置root密码怎么办_无法给MySQL root用户修改密码的解决方法
  14. JSP基于web网上作业提交系统
  15. 服务器项目迁移本地,云服务器迁移本地
  16. 知物由学 | iOS AssetBundle资源保护
  17. 破解微信数据库 并查询数据上传服务器
  18. InvocationException: GraphViz‘s executables not found【BUG已解决】
  19. ip地址分类及各网段私有地址
  20. 求数组中顺序子集和最大的值(详细图解)

热门文章

  1. Spring Boot——Spring Security环境下跨域addCorsMappings与拦截器冲突导致跨域失效解决方案
  2. MASM + DOSBox——debug.exe错误[Extended Error 2]解决方案
  3. C/C++程序设计IDE推荐
  4. 初级php工程师应该具备什么,一名合格的PHP工程师需要掌握的知识结构
  5. java正则表达式验证密码_java密码验证正则表达式校验
  6. 操作系统 课堂练习题01【15道 经典题目】
  7. 2018.5.5信息安全铁人三项赛数据赛复现
  8. try catch finally语句详解
  9. 安装ubuntu 13.04
  10. mvc 404错误 php,ASP.NET MVC实现404跳转的代码实例