一起学习springboot源码(系统初始化器)

Posted sirius-sen

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了一起学习springboot源码(系统初始化器)相关的知识,希望对你有一定的参考价值。

一、介绍

在初始化过程中,会进行配置系统初始化器

 技术图片

 

1、类名:ApplicationContextInitializer

2、介绍:他是spring容器刷新之前执行的一个回调函数

3、作用:向springboot容器中注册属性

4、使用:继承接口自定义实现

系统初始化器是springboot框架预留的一个扩展点,通过它我们可以在springboot容器刷新之前来向我们的容器中来注册属性

二、实现一个自定义初始化器,直接上代码

自定义初始化器,实现ApplicationContextInitializer

技术图片

 

 key值是context.initializer.classes,在application.properties中加入context.initializer.classes=com.demo.initializer.DemoInitializer

启动DemoApplication

技术图片

 

 可以看到,打印出了run demoInitializer,可以写一个DemoController,来测试获取数据

一共有三种实现方式,在这里只是举例其中的一种

 三、如何被springboot容器识别并注册进去

通过SpringFactoriesLoader类

技术图片

 

 

1、框架内部使用的通用工厂加载机制

2、从classpath下多个jar包特定的位置读取文件并初始化类

3、文件内容必须是key-value形式,即Properties类型

4、key是全限定名(抽象类、接口)、value是实现,多个实现用,分隔

五、初始化器流程,如何被加载进springboot容器中

先进入getSpringFactoriesInstances(ApplicationContextInitializer.class)方法

技术图片

 

 

1、获得类加载器

2、获得所有的系统初始化器的实现类的全路径名,我们进入SpringFactoriesLoader.loadFactoryNames方法

技术图片

 

 

 (1)、查找缓存,如果存在就返回

(2)、通过classLoader去加载资源路径,FACTORIES_RESOURCE_LOCATION = "META-INF/spring.factories",会读取这个文件,会获取所有的jar包中的文件

(3)、如果文件存在,会通过PropertiesLoaderUtils.loadProperties进行读取,然后进行遍历操作,根据key获取值,然后通过StringUtils.commaDelimitedListToStringArray进行分割,然后依次加入到结果中

(4)、依次获取所有jar下的数据后,组装result

(5)、然后通过getOrDefault获取对应的集合

3、调用createSpringFactoriesInstances方法依次创建实例

技术图片

 

 4、通过AnnotationAwareOrderComparator进行排序

在demo中,有@Order(1)注解,根据大小进行排序

5、通过setInitializers注册到springboot容器中

技术图片

 

 6、总结流程

技术图片

 

 六、系统初始化实现是如何被调用的,以及原理

 进入run方法,在prepareContext步骤,进入方法,找到applyInitializers(context);方法,此方法就是调用初始化器

 

 技术图片

 

 在springboot的spring.factories中,可以找到DelegatingApplicationContextInitializer

 技术图片

 

 因为是实现的ApplicationContextInitializer继承自ConfigurableApplicationContext,所以会在run中遍历到

技术图片

 

 技术图片

 

 总结流程:

技术图片

 

 总结实现原理:

1、定义在spring.factories文件中被SpringFactoriesLoader发现注册

2、SpringApplication初始化完毕之后手动添加

3、定义成环境变量被DelegatingApplicationContextInitializer发现注册

以上是关于一起学习springboot源码(系统初始化器)的主要内容,如果未能解决你的问题,请参考以下文章

springboot源码解析-从源码角度分析系统初始化器的实现原理

springboot源码解析-自定义系统初始化器

springboot源码解析-自定义系统初始化器

springBoot学习笔记源码分析之springApplication初始化过程

Nginx视频教程 反向代理/https/openresty/lua实战

SpringBoot3.0源码启动流程源码解析 •下