【README】
1,本文主要编写了 初始化器例子并分析了其调用路径;
【1】Initializer 初始化器例子
【1.1】初始化器
编写2个初始化器
// 初始化器1
@Order(0)
public class Hello01Initializer implements ApplicationContextInitializer<ConfigurableApplicationContext> {
@Override
public void initialize(ConfigurableApplicationContext applicationContext) {
System.out.println("===log=== Hello01Initializer.initialize() start...");
ConfigurableEnvironment environment = applicationContext.getEnvironment();
Map<String, Object> map = new HashMap<>();
map.put("key1", "v1");
MapPropertySource mapPropertySource = new MapPropertySource("hello01Initializer", map);
environment.getPropertySources().addLast(mapPropertySource);
System.out.println("===log=== Hello01Initializer.initialize() over...");
}
}
// 初始化器2
@Order(0)
public class Hello02Initializer implements ApplicationContextInitializer<ConfigurableApplicationContext> {
@Override
public void initialize(ConfigurableApplicationContext applicationContext) {
System.out.println("===log=== Hello02Initializer.initialize() start...");
ConfigurableEnvironment environment = applicationContext.getEnvironment();
Map<String, Object> map = new HashMap<>();
map.put("k2", "v2");
MapPropertySource mapPropertySource = new MapPropertySource("hello02Initializer", map);
environment.getPropertySources().addLast(mapPropertySource);
System.out.println("===log=== Hello02Initializer.initialize() over...");
}
}
【1.2】配置初始化器
在 spring.factories 配置 初始化器1 ,如下
# 初始化器
org.springframework.context.ApplicationContextInitializer=\
com.cmc.tr.springbt02config02.initializer.Hello01Initializer
在主程序中添加初始化器2 ;
@SpringBootApplication
public class Springbt02Config02Application {
public static void main(String[] args) {
SpringApplication springApplication = new SpringApplication(Springbt02Config02Application.class);
// 添加初始化器2
springApplication.addInitializers(new Hello02Initializer());
springApplication.run(args);
}
}
打印结果:
===log=== Hello01Initializer.initialize() start...
===log=== Hello01Initializer.initialize() over...
===log=== Hello02Initializer.initialize() start...
===log=== Hello02Initializer.initialize() over...
很明显, 初始化器1 的加载顺序, 先于 初始化器2 ;
【2】调用路径
【2.1】查看调用栈
调用路径大致为:
step1, SpringApplication.run() 方法;
从上图,我们看到, 初始化器是从 prepareContext() 开始调用的;
而 后置处理器是从 refreshContext() 开始调用的; 后置处理器 refer2 springboot:BeanPostProcessor示例及分析_PacosonSWJTU的博客-CSDN博客 ;
(干货)所以 初始化器的执行顺序 先于 后置处理器;
【补充】 关于 SpringApplication.refreshContext() 方法逻辑,包括但不限于(我这里没有列举完)
- 创建bean;
- 执行bean 后置处理器;
- 执行 InitializerBean 的afterPropertiesSet() 方法;
step2, SpringApplication.prepareContext(); 方法;
step3, SpringApplication.applyInitializers() 应用初始化器方法;
step4,调用自定义初始化器方法.initialize() 方法;