【Spring Boot 源码学习】BootstrapContext的实际使用场景

《Spring Boot 源码学习系列》

在这里插入图片描述

BootstrapContext的实际使用场景

  • 一、引言
  • 二、往期内容
  • 三、主要内容
    • 3.1 BootstrapContext
    • 3.2 BootstrapRegistry 初始化器实现
    • 3.3 BootstrapContext 的实际使用场景
      • 3.3.1 早期启动时
      • 3.3.2 环境配置准备完成时
      • 3.3.3 应用上下文准备完成后关闭 `BootstrapContext`
    • 3.4 实际使用演示
  • 四、总结

一、引言

上一篇博文《BootstrapRegistry 初始化器实现》,Huazie 向大家介绍了如何自定义 BootstrapRegistryInitializer 接口实现,并以此来执行自定义的初始化操作【如注册自定义的 Bean、添加 BootstrapContext 关闭监听器】。其中涉及到了 BootstrapContext 的部分使用场景,那本篇就向大家演示下 Spring Boot 启动过程中如何使用引用上下文 BootstrapContext 及其默认实现 。

在这里插入图片描述

二、往期内容

在开始本篇的内容介绍之前,我们先来看看往期的系列文章【有需要的朋友,欢迎关注系列专栏】:

Spring Boot 源码学习
Spring Boot 项目介绍
Spring Boot 核心运行原理介绍
【Spring Boot 源码学习】@EnableAutoConfiguration 注解
【Spring Boot 源码学习】@SpringBootApplication 注解
【Spring Boot 源码学习】走近 AutoConfigurationImportSelector
【Spring Boot 源码学习】自动装配流程源码解析(上)
【Spring Boot 源码学习】自动装配流程源码解析(下)
【Spring Boot 源码学习】深入 FilteringSpringBootCondition
【Spring Boot 源码学习】OnClassCondition 详解
【Spring Boot 源码学习】OnBeanCondition 详解
【Spring Boot 源码学习】OnWebApplicationCondition 详解
【Spring Boot 源码学习】@Conditional 条件注解
【Spring Boot 源码学习】HttpEncodingAutoConfiguration 详解
【Spring Boot 源码学习】RedisAutoConfiguration 详解
【Spring Boot 源码学习】JedisConnectionConfiguration 详解
【Spring Boot 源码学习】初识 SpringApplication
【Spring Boot 源码学习】Banner 信息打印流程
【Spring Boot 源码学习】自定义 Banner 信息打印
【Spring Boot 源码学习】BootstrapRegistryInitializer 详解
【Spring Boot 源码学习】ApplicationContextInitializer 详解
【Spring Boot 源码学习】ApplicationListener 详解
【Spring Boot 源码学习】SpringApplication 的定制化介绍
【Spring Boot 源码学习】BootstrapRegistry 详解
【Spring Boot 源码学习】深入 BootstrapContext 及其默认实现
【Spring Boot 源码学习】BootstrapRegistry 初始化器实现

三、主要内容

注意: 以下涉及 Spring Boot 源码 均来自版本 2.7.9,其他版本有所出入,可自行查看源码。

3.1 BootstrapContext

在 《深入 BootstrapContext 及其默认实现》 中,Huazie 详细介绍了引导上下文 BootstrapContext 及其默认实现 DefaultBootstrapContext,在继续下面的内容之前,有不知道的朋友们可以去回顾一下,这里不再赘述。

3.2 BootstrapRegistry 初始化器实现

在开始讲解 BootstrapContext 的实际使用场景之前,我们需要首先通过 BootstrapRegistry 初始化器实现类 注册自定义的对象,以便后续在实际的场景中通过 BootstrapContext 来获取。

这块内容,有需要了解的朋友,请翻看 Huazie 的上一篇博文《BootstrapRegistry 初始化器实现》,这里不再赘述。

3.3 BootstrapContext 的实际使用场景

首先我们需要通过源码来明确下需要 添加哪些内容,哪些场景和引导上下文有关?

先来看如下的截图【SpringApplication##run】:

在这里插入图片描述

从上面可以看到 BootstrapContext 实际上有 3 处使用场景,分别是:

  • 早期启动时
  • 环境配置准备完成时
  • 应用上下文准备完成后关闭 BootstrapContext

3.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 中呢?

通过阅读相关的源码,可总结如下的两种方式:

  • META-INF/spring.factories 中添加 org.springframework.context.ApplicationListener 的配置。这种方式,我们从 《ApplicationListener 详解》 的 3.2 小节可见一斑。
  • 通过 SpringApplication 中的 addListeners 方法添加。这里其实在笔者的《SpringApplication 的定制化介绍》中的 1.7 小节也提及过。

有关监听器实现 Ordered 接口,这里再次提及下:它可以用来确保多个监听同一事件的监听器可以按照我们预定的顺序执行。

3.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 中,显然跟 3.4.1 中的 DemoStartingListener 一样,等下会通过 SpringApplication 进行添加演示。

3.3.3 应用上下文准备完成后关闭 BootstrapContext

最后,我们看看准备应用上下文的源码截图:

在这里插入图片描述
在这里插入图片描述

从上述截图中,我们可以看出的确是在应用上下文准备完成后,调用了 DefaultBootstrapContextclose 方法,多播了 BootstrapContextClosedEvent 事件。我们如果想要监听这个事件,只需要实现对应的事件监听器,不过添加该监听器就不像 3.4.13.4.2 那样了。其实在 3.2 小节介绍的《BootstrapRegistry 初始化器实现》中,我们已经介绍了如何添加 BootstrapContext 关闭事件 监听器,这里就不再赘述。

3.4 实际使用演示

BootstrapContext 的实际使用场景已经在 3.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);
    }
}

修改好启动类的代码,我们就可以来运行了,如下截图:

在这里插入图片描述
从上述截图中,我们可以看到 3.3 中介绍的 3 个实际使用场景,已经全部打印日志信息了,说明定义的监听器已经执行了。

四、总结

本篇 Huazie 通过介绍 BootstrapContext 的实际使用场景,并演示了引导上下文在这些场景的实际使用,加深了大家对于 Spring Boot 的启动引导过程的了解,为后续的源码分析打下基础。

后续的博文,Huazie 就将从 SpringApplicationrun 方法入手,开始介绍 Spring Boot 的运行流程,敬请期待!

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:/a/442863.html

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈qq邮箱809451989@qq.com,一经查实,立即删除!

相关文章

Normalizer(归一化)和MinMaxScaler(最小-最大标准化)的区别详解

1.Normalizer&#xff08;归一化&#xff09;&#xff08;更加推荐使用&#xff09; 优点&#xff1a;将每个样本向量的欧几里德长度缩放为1&#xff0c;适用于计算样本之间的相似性。 缺点&#xff1a;只对每个样本的特征进行缩放&#xff0c;不保留原始数据的分布形状。 公式…

Linux--gdb(调试工具)

1. 背景 程序的发布方式有两种&#xff0c;debug模式和release模式 Linux gcc/g出来的二进制程序&#xff0c;默认是release模式 要使用gdb调试&#xff0c;必须在源代码生成二进制程序的时候, 加上 -g 选项 2. 命令 gdb binFile 退出&#xff1a; ctrl d 或 quit 调试命令&am…

如何压缩PDF文件大小?看完这篇文章,即可实现无损压缩!

平时工作或生活中&#xff0c;很多小伙伴是不是经常喜欢用PDF格式进行文件的保存&#xff0c;毕竟它具有较高的兼容性&#xff0c;且在不同设备中打开也不会出现排版错乱的情况。不过有时候PDF文件会因为内容过大&#xff0c;占用的内存过多&#xff0c;从而导致电脑卡顿的情况…

深入理解MySQL中的MVCC(多版本并发控制)

在MySQL中&#xff0c;MVCC是一种用于提供并发控制的技术&#xff0c;它允许数据库系统在事务并发执行的情况下保持数据的一致性&#xff0c;同时提高了数据库的并发性能。MVCC背后的理念是允许每个事务可以看到一个一致性的快照&#xff0c;从而避免了读取操作被写入操作所阻塞…

【Python刷题】环形链表

问题描述 给你一个链表的头节点 head &#xff0c;判断链表中是否有环。 如果链表中有某个节点&#xff0c;可以通过连续跟踪 next 指针再次到达&#xff0c;则链表中存在环。 为了表示给定链表中的环&#xff0c;评测系统内部使用整数 pos 来表示链表尾连接到链表中的位置&a…

树网的和 题解

先放一张图 作为一道蓝题&#xff0c;其实快接近紫题了。 --------------------------------------不怎么华丽的分割线-------------------------------------- 前置芝士&#xff1a;树的直径 一个点的最远点( y y y)到这个最远点的最远点( p p p)一定是一条树的直径。 假若…

Winform窗体随着屏幕的DPI缩放,会引起窗体变形及字体变形,superTabControl标签字体大小不匹配

一、前言 superTabControl做的浏览器标签(cefsharp)在缩放比例(125%,150%时字体不协调) 物联网浏览器,定制浏览器,多媒体浏览器(支持H264)参考栏目文章即可 二、配置参数 app.manifest参数 dpiAware =true <application xmlns="urn:schemas-microsoft-c…

Python快速入门系列-1

Python快速入门系列 第一章: Python简介1.1 Python的历史与发展1.2 Python的优势与特点1.2.1 易学易用1.2.2 动态类型1.2.3 丰富的标准库与第三方库1.2.4 面向对象与函数式编程1.2.5 广泛应用领域 1.3 Python的应用领域 第一章: Python简介 1.1 Python的历史与发展 Python是一…

Vue+SpringBoot打造个人健康管理系统

目录 一、摘要1.1 项目介绍1.2 项目录屏 二、功能模块2.1 健康档案模块2.2 体检档案模块2.3 健康咨询模块 三、系统展示四、核心代码4.1 查询健康档案4.2 新增健康档案4.3 查询体检档案4.4 新增体检档案4.5 新增健康咨询 五、免责说明 一、摘要 1.1 项目介绍 基于JAVAVueSpri…

python 蓝桥杯之并查集

文章目录 总述合并过程查找过程算法实战实战1 总述 并查集&#xff08;Disjoint-set Union&#xff0c;简称并查集&#xff09;是一种用来管理元素分组情况的数据结构。它主要用于解决集合的合并与查询问题&#xff0c;通常涉及到以下两种操作&#xff1a; 合并&#xff08;Uni…

优化员工学习体验:企业内训APP的设计与开发方案详解

当下&#xff0c;设计并开发一款高效、便捷、个性化的企业内训APP已成为许多企业追求的目标。本文将探讨如何优化员工学习体验&#xff0c;以及企业内训APP的设计与开发方案。 一、了解员工需求 在设计和开发企业内训APP之前&#xff0c;首先需要深入了解员工的学习需求和偏好…

VSCode搭建ARM开发环境

为了构建Cortex M系列单片机免费开源的开发环境&#xff0c;网络上了解来看VSCODEGCCJLINK是一套比较高效的组合方式&#xff0c;下面记录环境搭建的流程。 我这边的PC环境为 WIN7专业版64bit。 需要用到的工具 Visual Studio CodeSTM32CubemxARM GCC 交叉编译工具链&#x…

“下个月AI觉醒,杀死奥特曼...”好莱坞上线首部AI制作的电影,长达90分钟,取材终结者2

下个月&#xff0c;愚人节&#xff0c;奥特曼危&#xff01; 美国当地时间3月6号&#xff0c;全球首部完全由AI制作的长篇电影《Our T2 Remake》在好莱坞举行首映礼&#xff0c;长达90分钟。 好家伙&#xff0c;“AI制作”&#xff0c;“90分钟”几个关键词一下子就吸引住了小…

安全先行,合规的内外网文件摆渡要重点关注什么?

内外网隔离在政府、军工部门、科研单位等已成为很常见的网络安全建设措施&#xff0c;内外网隔离是一种网络安全措施&#xff0c;用于保护内部网络免受外部网络的攻击和威胁。 内外网隔离的目的在于限制内外网之间的通信和数据交换&#xff0c;但网络隔离后&#xff0c;仍有数据…

CODESYS双通气缸功能块(ST源代码)

博途PLC双通气缸功能块请参考下面文章链接: https://rxxw-control.blog.csdn.net/article/details/136415539https://rxxw-control.blog.csdn.net/article/details/136415539CODESYS 结构变量使用 https://rxxw-control.blog.csdn.net/article/details/126248829

重塑语言智能未来:掌握Transformer,驱动AI与NLP创新实战

Transformer模型 Transformer是自然语言理解(Natural Language Understanding&#xff0c;NLU)的游戏规则改变者&#xff0c;NLU 是自然语言处理(Natural Language Processing&#xff0c;NLP)的一个子集。NLU已成为全球数字经济中AI 的支柱之一。 Transformer 模型标志着AI 新…

landsat遥感卫星地表温度LST计算教程

地表温度反演算法主要有以下三种&#xff1a;大气校正法&#xff08;也称为辐射传输方程&#xff1a;Radiative Transfer Equation——RTE&#xff09;、单通道算法和分裂窗算法。 大气校正法基本原理&#xff1a;首先估计大气对地表热辐射的影响, 然后把这部分大气影响从卫星传…

Android增量报告生成新方案

在开发精准测试覆盖率相关的功能时候&#xff0c;对于Android的增量报告&#xff0c;由于担心修改jacoco插件会影响App的打包&#xff0c;所以一直没有修改。在网上查了一下&#xff0c;没有找到合适的方案。只有一个diff-cover开源项目&#xff1a;https://github.com/abmaonl…

阿里云ECS u1服务器2核4G5M带宽优惠价199元/年性能测评

阿里云服务器ECS u1实例&#xff0c;2核4G&#xff0c;5M固定带宽&#xff0c;80G ESSD Entry盘优惠价格199元一年&#xff0c;性能很不错&#xff0c;CPU采用Intel Xeon Platinum可扩展处理器&#xff0c;购买限制条件为企业客户专享&#xff0c;实名认证信息是企业用户即可&a…

【编程实践】matlab中的转义字符

简记 这个报错是因为在sprintf函数中使用了无效的转义字符\U。在MATLAB中&#xff0c;转义字符\U是无效的&#xff0c;因此会导致警告。 检查sprintf函数中的格式化字符串是否包含了无效的转义字符。确保只使用MATLAB支持的转义字符。 如果想要输出一个反斜杠字符\&#xff0c…