一起学习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发现注册

原文地址:https://www.cnblogs.com/sirius-sen/p/12632424.html

时间: 2024-11-05 23:46:35

一起学习springboot源码(系统初始化器)的相关文章

Linux学习之源码2:start_kernel流程

一.X86的流程可以参考http://www.kerneltravel.net/kernel-book/第十三章%20启动系统/13.5.htm 二.arm的流程,在http://www.cnblogs.com/gangsaleisi/archive/2013/01/09/2851734.html基础上进行分析. 并且是在3.9.7版本上进行分析的,差别不是太大. 1.lockdep_init():lockdep哈希表初始化,lockdep是linux内核的一个调试模块,用来检查内核互斥机制尤其

SpringBoot的启动流程是怎样的?SpringBoot源码(七)

注:该源码分析对应SpringBoot版本为2.1.0.RELEASE 1 温故而知新 本篇接 SpringBoot内置的各种Starter是怎样构建的? SpringBoot源码(六) 温故而知新,我们来简单回顾一下上篇的内容,上一篇我们分析了SpringBootSpringBoot内置的各种Starter是怎样构建的?,现将关键点重新回顾总结下: spring-boot-starter-xxx起步依赖没有一行代码,而是直接或间接依赖了xxx-autoconfigure模块,而xxx-auto

如何分析SpringBoot源码模块及结构?--SpringBoot源码(二)

注:该源码分析对应SpringBoot版本为2.1.0.RELEASE 1 前言 本篇接如何搭建自己的SpringBoot源码调试环境?--SpringBoot源码(一). 前面搭建好了自己本地的SpringBoot源码调试环境后,此时我们不要急着下手进入到具体的源码调试细节中,刚开始阅读源码,此时我们一定要对项目结构等有一个整体的认识,然后再进行源码分析调试.推荐阅读下笔者之前写的的分析开源项目源码,我们该如何入手分析?一文,干货满满哦. 2 SpringBoot源码模块一览 我们先来对Spr

SpringBoot是如何实现自动配置的?--SpringBoot源码(四)

注:该源码分析对应SpringBoot版本为2.1.0.RELEASE 1 前言 本篇接助力SpringBoot自动配置的条件注解ConditionalOnXXX分析--SpringBoot源码(三) 温故而知新,我们来简单回顾一下上篇的内容,上一篇我们分析了SpringBoot的条件注解@ConditionalOnXxx的相关源码,现挑重点总结如下: SpringBoot的所有@ConditionalOnXxx的条件类OnXxxCondition都是继承于SpringBootCondition

SpringBoot内置的各种Starter是怎样构建的?--SpringBoot源码(六)

注:该源码分析对应SpringBoot版本为2.1.0.RELEASE 1 温故而知新 本篇接 外部配置属性值是如何被绑定到XxxProperties类属性上的?--SpringBoot源码(五) 温故而知新,我们来简单回顾一下上篇的内容,上一篇我们分析了SpringBoot外部配置属性值是如何被绑定到XxxProperties类属性上的相关源码,现将外部属性绑定的重要步骤总结如下: 首先是@EnableConfigurationProperties注解import了EnableConfigur

SpringApplication对象是如何构建的? SpringBoot源码(八)

注:该源码分析对应SpringBoot版本为2.1.0.RELEASE 本篇接 SpringBoot的启动流程是怎样的?SpringBoot源码(七) 1 温故而知新 温故而知新,我们来简单回顾一下上篇的内容,上一篇我们分析了SpringBoot的启动流程,现将关键步骤再浓缩总结下: 构建SpringApplication对象,用于启动SpringBoot: 从spring.factories配置文件中加载EventPublishingRunListener对象用于在不同的启动阶段发射不同的生命

一起学习redis源码

redis的一些介绍,麻烦阅读前面的几篇文章,想对redis的详细实现有所了解,强力推荐<redis设计与实现>(不仅仅从作者那儿学习到redis的实现,还有项目的管理.思想等,作者可能比你我都年轻欧).如果阅读了上面的文档,激起你对redis的强力好奇,那么就只能阅读源码了.不管是在校学生,还是已工作的,redis的代码都值得阅读.我们可以了解如何编写一个工程可用软件,可以学习一些开源常用软件,通过redis丰富的数据结构,可以熟悉大学学习的那点儿数据结构,可以了解如何实现一个自己高效的网络

Linux学习之源码1:入口流程

有地方看到,启动流程是arch/arm/boot/compressed/head.s ----->调用arch/arm/boot/compressed/misc.c的decompress_kernel()函数解压内核.---->arch/arm/kernel/head-common.S初始化 ---->init/main.c的asmlinkage void __init start_kernel(void) 注意在arch/arm/kernel/smp.c文件中有一个启动多核处理器的函数

Android FM模块学习之四源码解析(二)

上一章我们了解了FM主activity:FMRadio.java,若没查看的,请打开链接Android FM模块学习之四源码解析(一) 查看fmradio.java源码注释.接下来我们来看看FM重要的一个类:FMRadioService.java 由上一章我们已经知道,打开FM时,在OnStart函数中会bindToService来开启服务, public boolean bindToService(Context context, ServiceConnection callback) { L