Spring Boot系统初始化器
大约 2 分钟Spring BootApplicationContextInitializerSpring Boot
概述
系统初始化器类名为ApplicationContextInitializer
,是ApplicationContextInitializerSpring.initialize
容器刷新之前执行的一个回调函数,作用是向SpringBoot容器中注册属性。
使用
声明自定义初始化器注入属性到容器中
package tech.xiangwang.sbdemo.initializer;
import org.springframework.context.ApplicationContextInitializer;
import org.springframework.context.ConfigurableApplicationContext;
import org.springframework.core.env.ConfigurableEnvironment;
import org.springframework.core.env.MapPropertySource;
import java.util.HashMap;
import java.util.Map;
/**
* @description:
* @author: blog.xiangwang.tech
* @create: 2022-12-03 16:57
**/
public class TestInitializer implements ApplicationContextInitializer<ConfigurableApplicationContext> {
@Override
public void initialize(ConfigurableApplicationContext applicationContext) {
ConfigurableEnvironment environment = applicationContext.getEnvironment();
Map<String, Object > map = new HashMap<>();
map.put("key1", "value1");
MapPropertySource mapPropertySource = new MapPropertySource("first",map);
environment.getPropertySources().addLast(mapPropertySource);
System.out.println("run TestInitializer");
}
}
有三种方式将初始化器进行注册:
定义在
src/main/resources/META-INF/spring.factories
文件中被SpringFactoriesLoader
注册发现。org.springframework.context.ApplicationContextInitializer =tech.xiangwang.sbdemo.initializer.TestInitializer
SpringApplication初始化完毕后手动添加
@SpringBootApplication public class SbDemoApplication { public static void main(String[] args) { SpringApplication springApplication = new SpringApplication(SbDemoApplication.class); springApplication.addInitializers(new TestInitializer()); springApplication.run(args); } }
在
src/main/resources/application.properties
定义成环境变量被DelegatingApplicationContextInitializer
发现注册。context.initializer.classes=tech.xiangwang.sbdemo.initializer.TestInitializer
流程
SpringFactoriesLoader 读取初始化器代码如下
进一步查看org.springframework.core.io.support.SpringFactoriesLoader#loadFactoryNames
方法,
流程:从classpath下多个jar包读取META-INF/spring.factories读取文件并初始化类,文件内容必须是kv形式,即properties类型,key是全限定名(接口、抽象类)、value是实现,多个实现用,分隔
初始化器执行时机在准备上下文阶段,org.springframework.boot.SpringApplication#applyInitializers
方法会将上方法返回的初始化器进行初始化操作,debug视图如下,
排序根据Order从小到大的顺序进行依次执行
总结
- 初始化器用于向容器中注册属性和环境配置
SpringFactoriesLoader
这个类实现了检索META-INF/spring.factories文件,并获取指定接口的配置的功能。在很多内置的start模块有使用到了该配置,可以做到自动配置,达到开箱即用的效果。