在之前文章中说过,springBoot会根据jar包去添加许多的自动配置,本文就来说说为什么会自动配置,自动配置的原理时什么?

  springBoot在运行SpringApplication对象实例化时,就会去加载 META-INF/spring.factories文件,就会将这个文件中的配置都加载到spring容器中。下面,我们去看看SpringApplication对象的初始化方法 initialize() 方法。

  因为我们在项目启动时有用到这个对象,所以,我们可以直接从这里进入。

  找到 initialize()方法,发现,在其中存在一个获取初始化参数的方法。

  我们继续向下跟进。

  继续跟进,我发现里面存在两个方法,第一个获取配置中的类的名字,第二个将配置中的类创建为一个个对象。

  接下来,我先跟进SpringFactoriesLoader.loadFactoryNames()方法。(笔记本屏幕显示不下,所以直接拉代码过来,就不截图了)

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);
}
}

  我发现上面使用到一个常量 FACTORIES_RESOURCE_LOCATION ,去找到这个常量。

  这个常量存放了一个文件位置,而这个文件中存放的就是自动配置的一个个对象。去找到它们。

  找到这些对象之后,继续执行createSpringFactoriesInstances()方法。将上面获取到的对象名称全部实例化为一个个对象。

  在spring-boot-autoconfigure的包下,也同样有一个spring.factories文件,上面的文件中主要包含的是一些系统级的自动配置,而在spring-boot-autoconfigure包下的则是一些第三方的自动配置,比如下面的redis等等。

  我们进入到redis去看看,我发现在其头部有一句注解@ConditionalOnClass,这个注解的意思是,只有系统中有这几个类时,才会去加载配置这个类,如果没有则不去加载配置。

  在下面这个对象中,自动去加载redis的配置

  而这些配置参数则时去 application.properties文件中去找的,这个文件中的基础配置在我之前的文章中有写过(springBoot application.properties 基础配置)。

  以上就是springBoot的自动化配置的原理,当然,我们知道了这些原理,其实就可以模仿这种方式在项目中加入自定义的自动化配置。

  最后附上一些条件注解,在上面的自动化配置中也经常使用到。

注解 解释
@ConditionalOnBean 当容器中有指定Bean的条件下
@ConditionalOnClass 当路径下有指定类的条件下
@ConditionalOnExpression 基于SqEL表达式作为判断条件
@ConditionalOnJava 基于JVM版本作为判断条件
@ConditionalOnJndi 在JNDI存在的条件下查找指定位置
@ConditionalOnMissingBean 当容器中没有指定Bean的情况下
@ConditionalOnMissingClass 当类路径下没有指定的类的条件下
@ConditionalOnNotWebApplication 当前项目不是Web项目的情况下
@ConditionalOnProperty 指定的属性是否有指定的值
@ConditionalOnResource 类路径是否有指定的值
@ConditionalOnSingleCandidate 当前指定Bean在容器中只有一个,或者虽然有多个但是指定首选的Bean
@ConditionalOnWebApplication 当前项目时Web项目的条件下

-------------------- END ---------------------


最后附上作者的微信公众号地址和博客地址


公众号:wuyouxin_gzh




Herrt灬凌夜:https://www.cnblogs.com/wuyx/

springBoot 自动配置原理的更多相关文章

  1. 这样讲 SpringBoot 自动配置原理,你应该能明白了吧

    https://juejin.im/post/5ce5effb6fb9a07f0b039a14 前言 小伙伴们是否想起曾经被 SSM 整合支配的恐惧?相信很多小伙伴都是有过这样的经历的,一大堆配置问题 ...

  2. springboot自动配置原理以及手动实现配置类

    springboot自动配置原理以及手动实现配置类 1.原理 spring有一个思想是"约定大于配置". 配置类自动配置可以帮助开发人员更加专注于业务逻辑开发,springboot ...

  3. SpringBoot自动配置原理

    前言 只有光头才能变强. 文本已收录至我的GitHub仓库,欢迎Star:https://github.com/ZhongFuCheng3y/3y 回顾前面Spring的文章(以学习的顺序排好): S ...

  4. SpringBoot实战之SpringBoot自动配置原理

    SpringBoot 自动配置主要通过 @EnableAutoConfiguration, @Conditional, @EnableConfigurationProperties 或者 @Confi ...

  5. 3. SpringBoot ——自动配置原理浅析

    SpringBoot的功能之所以强大,离不开它的自动配置这一大特色.但估计很多人只是知其然而不知其所以然.下面本人对自动配置原理做一个分析: 在使用SpringBoot时我们通过引入不同的Starte ...

  6. SpringBoot自动配置原理学习

    介绍 构建Springboot项目时我们会创建一个启动类 @SpringBootApplication public class DemoApplication { public static voi ...

  7. 浅谈springboot自动配置原理

    前言 springboot自动配置关键在于@SpringBootApplication注解,启动类之所以作为项目启动的入口,也是因为该注解,下面浅谈下这个注解的作用和实现原理 @SpringBootA ...

  8. SpringBoot系列二:SpringBoot自动配置原理

    主程序类的注解 @SpringBootApplication 注解,它其实是个组合注解,源码如下: @Target({ElementType.TYPE}) @Retention(RetentionPo ...

  9. springBoot 自动配置原理--自己新建一个 starter

    上篇我们说到 springboot 和 SSM 框架的区别,今天我们就看看 springboot 到底为我们做了哪些事情,让我们开发变得如此简单. springboot 中起着重要作用的是 start ...

随机推荐

  1. Happy Matt Friends(HDU5119 + dp)

    题目链接: http://acm.hdu.edu.cn/showproblem.php?pid=5119 题目: 题意: 求选择任意个数,使其异或和大于等于m的方案数. 思路: 每个数有选和不选两种方 ...

  2. Python练习-基于授权方式包装list之与根儿哥必有一战

    # 编辑者:闫龙 # 基于授权定制自己的列表类型,要求定制的自己的__init__方法, # 定制自己的append:只能向列表加入字符串类型的值 # 定制显示列表中间那个值的属性(提示:proper ...

  3. Python练习-不知道弄个什么鬼

    Alex大神,今天丢过来一个PDF,结果就成了这个样子! 1.  执行 Python 脚本的两种方式 交互方式:                   命令行 文件方式:                 ...

  4. jquery对不同id的按钮执行同一类型的操作

    不同id执行相同操作: $("#id1,#id2,#id3,#id4") 获取相同class的text值: $(".className").each(funct ...

  5. (一)利用 mdb 调试获取 nvlist_t 中 nvpair_t(name/value) 对

    服务器:192.168.2.122 root@2236:~# mdb -k> ::spaADDR                 STATE NAME                       ...

  6. c++细节--section1

    1.register声明的变量为寄存器变量,因此没有地址,不能对它取地址操作. 2.[用错sizeof]当数组作为函数参数传递时,数组会退化为同类型的指针. 3.每个成员在成员初始化列表中只能出现一次 ...

  7. python入门 20141102-1405

    那Python有哪些缺点呢? 第一个缺点就是运行速度慢,和C程序相比非常慢, 第二个缺点就是代码不能加密. Python是解释型的 不是编译型的 Python解释器-CPython 命令行: 只需要在 ...

  8. css单行文本和多行文本溢出实现省略号显示

    1.单行文本溢出 文本内容 <div class="singleLine"> HelloWorldHelloWorldHelloWorldHelloWorldHello ...

  9. Web测试技术要领

    基于Web的系统测试与传统的软件测试既有相同之处,也有不同的地方,对软件测试提出了新的挑战.基于Web的系统测试不但需要检查和验证是否按照设计的要求运行,而且还要评价系统在不同用户的浏览器端的显示是否 ...

  10. 使用postman做接口测试(一)

    参考大神的总结:https://www.cnblogs.com/Skyyj/p/6856728.html 一,先了解一下基础知识,虽然工作中没什么卵用,但背会了,可以显摆自己很专业的样子,以下内容来自 ...