SpringBoot(三)SpringBoot自动配置
我们都知道SpringBoot帮助我们集成了许多组件和配置,那么SpringBoot是如何集成这些配置并在启动是自动进行配置呢。说到这就不得又需要回过头来看一下@SpringBootApplication这个注解了,之前已经说过这个注解是@Configuration,@EnableAutoConfiguration,@ComponentScan三个注解的组合,这里需要特殊强调下@EnableAutoConfiguration这个注解,没错就是这个注解使SpringBoot完成自动配置的。@EnableAutoConfiguration-----@Import(EnableAutoConfigurationImportSelector.class)-----AutoConfigurationImportSelector按照这个顺序我们可以进入SpringBoot的自动配置导入选择器。接下来我们就看一下SpringBoot是如何完成自动配置并观摩下源码。
public 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);
Set<String> exclusions = getExclusions(annotationMetadata, attributes);
14 checkExcludedClasses(configurations, exclusions);
configurations.removeAll(exclusions);
configurations = filter(configurations, autoConfigurationMetadata); //从11行到16进行移除未完全集成的配置并进行排序和过滤
fireAutoConfigurationImportEvents(configurations, exclusions); //导入过滤后的组件
return configurations.toArray(new String[configurations.size()]);
}
catch (IOException ex) {
throw new IllegalStateException(ex);
}
}
上面代码是进行自动配置的主方法,其实操作流程我在注释上已经进行了简单的说明
1.先对原数据进行判断是否为空再进行具体操作
2.加载原数据并获取属性
3.获取配置信息 (其实最重要的就是第三点因为如何获取配置信息并进行加载才是我们最关心的也是SpringBoot中最核心的部分)
4.移除未完全集成的配置并进行排序过滤 (由于有些配置SpringBoot并没有给我们进行完全配置,需要我们自己进行手动配置,这里之所以这么做个人认为如果SpringBoot把所有的组件都进行集成那么对项目本身启动来说就会造成一定的压力,毕竟有些组件在有些项目中并不需要使用)
5.导入处理后的组件配置
这里我们需要着重强调下getCandidateConfigurations这个方法,看看SpringBoot是如何获取组件的。
protected List<String> getCandidateConfigurations(AnnotationMetadata metadata,
AnnotationAttributes attributes) {
List<String> configurations = SpringFactoriesLoader.loadFactoryNames( //Spring工厂进行加载获取配置信息
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."); //如果配置不为空返回配置信息否则说明在META-INF/spring.factories这个目录下没有找到配置信息
return configurations;
}
public static final String FACTORIES_RESOURCE_LOCATION = "META-INF/spring.factories";
public static List<String> loadFactoryNames(Class<?> factoryClass, ClassLoader classLoader) {
String factoryClassName = factoryClass.getName();
try {
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 = PropertiesLoaderUtils.loadProperties(new UrlResource(url));
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);
}
}


相信看到这里已经不需要我过多的说明了,简而言之就是SpringBoot会去"META-INF/spring.factories"目录中去获取配置信息,然后再去做自动配置,现在我们在回过头来看最初SpringBoot进行自动配置的方法,我们走debug看一下。

这里我们可以看到SpringBoot在没有进行移除和过滤之前他在目录中获取到了96个组件下面再看一下过滤之后的。

过滤之后还有20个,也就是说SpringBoot为我们完全集成并自动配置的有20个组件,如果需要其他组件我们自己进行手动配置。(版本不动支持的组件数量或许有变化这里我是用的是1.5.9的版本)
除了这种方式还有其他方式来确定SpringBoot为我们自动配置了哪些组件么?如果这样看的话确实麻烦了写毕竟我们不可能每次都要在启动的时候通过debug来确认哪些是否被自动配置了,SpringBoot提供了debug启动模式让我们在控制台中就可以看到哪些进行了自动配置哪些没有完成自动配置,话不多说上图



Positive matches: 已经自动配置的 Negative matches:没有自动配置,以上就是SpringBoot如何完成自动配置的,其实自动配置这块想了好久要不要写,毕竟SpringBoot核心的配置,也怕有些地方写错了会误导其他人,也希望看到这篇文章的,看到有错误的地方希望能指正出来,互相学习互相进步,我不是一个勤快的人,但我希望能够改变当前懒散的状态,直到现在还记的我大学老师的一句话,只要开始永远不晚,只要努力就会成功,或许有鸡汤的成分,但还是希望只要开始永远不晚。
在很长的一段时间我变的颓废混日子,甚至忘了当初选择这个行业的初衷,总是喜欢抱怨种种得不公,我希望以后的日子我能找回那个努力的自己,没有人愿意平平淡淡,碌碌无为过一生,不求无愧于他人,但求无愧于自己,也希望每个在这个行业里为之坚持的伙伴我们都能无愧于自己,成为那个想象中的自己。
SpringBoot(三)SpringBoot自动配置的更多相关文章
- Springboot学习03-SpringMVC自动配置
Springboot学习03-SpringMVC自动配置 前言 在SpringBoot官网对于SpringMVCde 自动配置介绍 1-原文介绍如下: Spring MVC Auto-configur ...
- 【玩转SpringBoot】给自动配置来个整体大揭秘
上一篇文章中提到的条件注解,只是自动配置整体解决方案中的一个环节而已,可以说是管中窥豹. 本文就逐步擦除迷雾,让整体浮现出来,这样就会有一个宏观的认识. 除了写代码之外,还能干点什么? 提到“配置”这 ...
- Springboot 禁用数据库自动配置
转载至:https://blog.csdn.net/wyw815514636/article/details/80846545 https://blog.csdn.net/knqi007/articl ...
- SpringBoot 系列教程自动配置选择生效
191214-SpringBoot 系列教程自动配置选择生效 写了这么久的 Spring 系列博文,发现了一个问题,之前所有的文章都是围绕的让一个东西生效:那么有没有反其道而行之的呢? 我们知道可以通 ...
- 【springboot】之自动配置原理
使用springboot开发web应用是很方便,只需要引入相对应的GAV就可以使用对应的功能,springboot默认会帮我们配置好一些常用配置.那么springboot是怎么做到的呢?这篇文章将一步 ...
- SpringBoot 三种方式配置 Druid(包括纯配置文件配置)
记录一下在项目中用纯 YML(application.yml 或者 application.properties)文件.Java 代码配置 Bean 和注解三种方式配置 Alibaba Druid 用 ...
- SpringBoot扩展SpringMVC自动配置
SpringBoot中自动配置了 ViewResolver(视图解析器) ContentNegotiatingViewResolver(组合所有的视图解析器) 自动配置了静态资源文件夹.静态首页.fa ...
- IntelliJ IDEA 2017版 SpringBoot的关闭自动配置和自定义Banner
一.关闭自动配置 在jar包下找下边的名字 设置关闭自动配置jar 多个的时候配置 二.自定义Banner (1)网站搜索一个图案.网址:http://patorjk.co ...
- SpringBoot日记——SpringMvc自动配置与扩展篇
为了让SpringBoot保持对SpringMVC的全面支持和扩展,而且还要维持SpringBoot不写xml配置的优势,我们需要添加一些简单的配置类即可实现: 通常我们使用的最多的注解是: @Bea ...
随机推荐
- python入门机器学习,3行代码搞定线性回归
本文着重是重新梳理一下线性回归的概念,至于几行代码实现,那个不重要,概念明确了,代码自然水到渠成. “机器学习”对于普通大众来说可能会比较陌生,但是“人工智能”这个词简直是太火了,即便是风云变化的股市 ...
- Git学习笔记(二) · 非典型性程序猿
远程库的使用 前面说到的都是git在本地的操作,那么实际协作开发过程中我们肯定是要有一个远程版本库作为项目的核心版本库,也就是投入生产使用的版本.这里我们以 Github为例.Github是一个开放的 ...
- 浅谈在ES5环境下实现const
最近看到一个面试题--用ES5实现const.作为JS初学者的笔者知道在ES6中有const命令,可以用来声明常量,一旦声明,常量的值就不可改变.例如: 1234567891011 const Pi ...
- 金矿还是大坑 VR创业真有那么美好?
VR创业真有那么美好?"> 近段时间,一个段子在疯狂流传:彩票中奖的1000万,其实是存放在银行里,而彩民每次花两块钱买彩票,其实就是去输一次密码,只要够坚持,总会取出那1000万-- ...
- Java-Springboot-集成spring-security简单示例(Version-springboot-2-1-3-RELEASE
使用Idea的Spring Initializr或者SpringBoot官网下载quickstart 添加依赖 1234 <dependency><groupId>org.sp ...
- IP 多播
IP 多播 一.IP 多播的基本概念 1.1.简介 不使用多播时需要发送 90 次单播: 使用多播时只需要发送 1 次多播: 1.2.IP 多播的一些特点 多播使用组地址:D 类IP地址支持多播.多播 ...
- #2020.1.26笔记——springdatajpa
2020.1.26笔记--springdatajpa 使用jpa的步骤: 1. 导入maven坐标 <?xml version="1.0" encoding="UT ...
- git指令-添加远程仓库
git指令-添加远程仓库 首先在GitHub上创建属于你自己的远程仓库:例如我创建的远程仓库mybatis用于我最近保存的mybatis代码 目前,在GitHub上的这个learngit仓库还是空的, ...
- qt creator源码全方面分析(3-2)
目录 qtcreator.pri 判断重复包含 定义版本信息 VERSION 定义IDE名称 启用C++14 CONFIG 自定义函数 Replace Functions Test Functions ...
- C++ 命令行窗口打印二叉树(图形)
写这个程序的目的是学习数据结构的时候方便调试,学习起来也比较直观. 这个是我测试SplayTree时候的gif STEP 1 新建一个头文件,命名为DrawATree.hh, 将以下内容复制进去 #i ...