【Spring Boot 源码学习】BootstrapContext的实际使用场景
一、引言
二、主要内容
注意: 以下涉及 Spring Boot 源码 均来自版本 2.7.9,其他版本有所出入,可自行查看源码。
2.1 BootstrapContext
2.2 BootstrapRegistry 初始化器实现
在开始讲解 BootstrapContext
的实际使用场景之前,我们需要首先通过 BootstrapRegistry
初始化器实现类 注册自定义的对象,以便后续在实际的场景中通过 BootstrapContext
来获取。
2.3 BootstrapContext 的实际使用场景
首先我们需要通过源码来明确下需要 添加哪些内容,哪些场景和引导上下文有关?
先来看如下的截图【SpringApplication##run
】:
从上面可以看到 BootstrapContext
实际上有 3 处使用场景,分别是:
- 早期启动时
- 环境配置准备完成时
- 应用上下文准备完成后关闭
BootstrapContext
2.3.1 早期启动时
首先我们来看看 早期启动时 的源码截图:
从上述截图可知,这里多播了 ApplicationStartingEvent
事件,我们如果想要监听这个事件,只需要实现对应的事件监听器,并添加到监听器列表 listeners
中即可。
下面我们来自定义有关 ApplicationStartingEvent
事件的监听器类:
public class DemoStartingListener implements ApplicationListener<ApplicationStartingEvent>, Ordered {
@Override
public void onApplicationEvent(ApplicationStartingEvent event) {
ConfigurableBootstrapContext bootstrapContext = event.getBootstrapContext();
User user = bootstrapContext.get(User.class);
System.out.println("启动时获取User:" + user);
user.setName("Huazie_1");
user.setAge(19);
}
@Override
public int getOrder() {
return 1;
}
}
上述代码中的 User
类只是一个简单的 POJO 对象,这里源码就不列出来了,可以自行定义即可。
那么上述自定义的监听器该如何添加到监听器列表 listeners
中呢?
通过阅读相关的源码,可总结如下的两种方式:
有关监听器实现 Ordered
接口,这里再次提及下:它可以用来确保多个监听同一事件的监听器可以按照我们预定的顺序执行。
2.3.2 环境配置准备完成时
接着,我们来看看 准备环境配置 的源码截图:
从上述截图可知,这里显然在环境配置准备完成之后,多播了 ApplicationEnvironmentPreparedEvent
事件,我们如果想要监听这个事件,只需要实现对应的事件监听器,并添加到监听器列表 listeners
中即可。
下面我们来自定义有关 ApplicationEnvironmentPreparedEvent
事件的监听器类:
public class DemoEnvironmentPreparedListener implements ApplicationListener<ApplicationEnvironmentPreparedEvent>, Ordered {
@Override
public void onApplicationEvent(ApplicationEnvironmentPreparedEvent event) {
ConfigurableBootstrapContext bootstrapContext = event.getBootstrapContext();
if (bootstrapContext.isRegistered(User.class)) {
User user = bootstrapContext.get(User.class);
System.out.println("环境准备时获取User:" + user);
user.setName("Huazie_2");
user.setAge(20);
}
}
@Override
public int getOrder() {
return 1;
}
}
至于该监听器如何添加到监听器列表 listeners
中,显然跟 2.3.1 中的 DemoStartingListener
一样,等下会通过 SpringApplication
进行添加演示。
2.3.3 应用上下文准备完成后关闭 BootstrapContext
最后,我们看看准备应用上下文的源码截图:
2.4 实际使用演示
BootstrapContext
的实际使用场景已经在 2.3 中介绍,下面 Huazie 就带大家实操下。
首先,Spring Boot 启动类中需要修改如下:
@SpringBootApplication
public class DemoApplication {
public static void main(String[] args) {
SpringApplication springApplication = new SpringApplication(DemoApplication.class);
// 关闭 Banner打印
springApplication.setBannerMode(Banner.Mode.OFF);
// 添加 BootstrapRegistry初始化器实现
springApplication.addBootstrapRegistryInitializer(new DemoBootstrapper());
// 添加 监听器实现
springApplication.addListeners(new DemoStartingListener(), new DemoEnvironmentPreparedListener());
springApplication.run(args);
}
}
修改好启动类的代码,我们就可以来运行了,如下截图:
从上述截图中,我们可以看到 2.3 中介绍的 3 个实际使用场景,已经全部打印日志信息了,说明定义的监听器已经执行了。
三、总结
本篇 Huazie 通过介绍 BootstrapContext
的实际使用场景,并演示了引导上下文在这些场景的实际使用,加深了大家对于 Spring Boot 的启动引导过程的了解,为后续的源码分析打下基础。
后续的博文,Huazie 就将从 SpringApplication
的 run
方法入手,开始介绍 Spring Boot 的运行流程,敬请期待!
转载自:https://juejin.cn/post/7395503605339422730