我们都知道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 ...
随机推荐
-
phpv6_css
global @charset "utf-8"; /* CSS Document */ /*格式化样式*/ body,div,dl,dt,dd,ul,ol,li,h1,h2,h3, ...
-
iconv 批量修改文件编码
iconv_shell.sh #!/bin/bash "];then echo "Usage: `basename $0` dir filter" exit fi dir ...
-
使用html5结构化元素
显示的效果如上边这样,但是有没有发现内容的外侧没有边线(这个难道是因为浏览器不同吗?有待测试) html5中新增加的元素<header>可以明确的告诉浏览器此处是页头,<nav> ...
-
Intent Flag实际项目 -- 超时跳转登录界面并清理前面所有activity
项目中涉及到登录超时跳转登录界面的逻辑,我以前的跳转flag为Intent.FLAG_ACTIVITY_CLEAR_TOP,但是点击返回按钮还是会回到上个界面.代码如下: ActivityUtils. ...
-
Before NOIP 2018
目录 总结 刷题 2018 - 9 - 24 2018 - 9 - 25 2018 - 9 - 26 2018 - 9 - 27 2018 - 9 - 28 2018 - 9 - 29 2018 - ...
-
[教程]微信官方开源UI库-WeUI使用方法【申明:来源于网络】
[教程]微信官方开源UI库-WeUI使用方法 [ 教程]微信官方开源UI库-WeUI使用方法 地址:http://www.weui.org.cn/?/article/1 微信公众号开发-WeUI使用说 ...
-
JDBC事务(三)ThreadLocal绑定Connection
处理一个请求即开启一个线程,在三层中,执行三层中的方法都是用的同一个线程. 我们开启一个事务,使用conn.setAutoCommit(false); conn应该属于ado层,不应该出现在servi ...
-
解决Ubuntu/debian的Apt-get 由于依赖关系安装失败的问题
The following packages have unmet dependencies: libssl-dev: Depends: libssl0.9.8 (= 0.9.8k-7ubuntu8) ...
-
layer.js 弹窗组件API文档
基础参数 type title content skin area offset icon btn closeBtn shade shadeClose time id shift maxmin f ...
-
Train-Alypay-Cloud:mPaaS 移动开发平台培训(第一次)
ylbtech-Train-Alypay-Cloud:mPaaS 移动开发平台培训(第一次) 1.返回顶部 1. 大家好! 欢迎大家参加蚂蚁金融云 即将在2018年1月17日到1月18日 在北京 环球 ...