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

news2024/11/15 8:00:22

《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 的运行流程,敬请期待!

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

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

如果要填写邀请码,但是不想新建窗体 还要有确定和取消按钮和逻辑判断使用模态对话框即可

如果要填写邀请码&#xff0c;但是不想新建窗体 还要有确定和取消按钮和逻辑判断 如果你不想新建窗体来填写邀请码&#xff0c;但又希望有确定和取消按钮以及逻辑判断&#xff0c; 如果你不想新建窗体&#xff0c;并且希望在需要时显示一个临时的文本框来填写邀请码&#xff…

遥感生态指数(RSEI)——四个指数的计算

遥感生态指数RSEI&#xff08;Risk-Screening Environmental Indicators&#xff09;分布数据是一种基于卫星遥感影像反演计算得到的数据产品。生态环境质量评价在一定程度上反映一个地区生态环境系统的好坏,也可以在一定程度上反映人类社会活动和环境质量的关系,其对可持续发展…

Sftp服务器搭建(linux)

Sftp服务器搭建&#xff08;linux&#xff09; 一、基本工作原理 FTP的基本工作原理如下&#xff1a; 1&#xff09;建立连接&#xff1a;客户端与服务器之间通过TCP/IP建立连接。默认情况下&#xff0c;FTP使用端口号21作为控制连接的端口。​​​​​​​ 2&#xff09;身…

Halcon棋盘格畸变矫正

前言 通常我们使用的相机都是带有一定的畸变的&#xff0c;只是畸变的大小不同。对于我们常见的测量项目来说&#xff0c;对测量精度的要求很高&#xff0c;通常从相机镜头上进行优化&#xff0c;但是即使镜头优化或者成本原因&#xff0c;造成图像仍有一定的畸变时&#xff0…

微信小程序-可以用区域

简介 movable-view和movable-area是可移动的视图容器&#xff0c;在页面中可以拖拽滑动。 本篇文章将会通过该容器实现一个常用的拖拽按钮功能。 使用效果 代码实现 side-view.wtml 布局见下面代码&#xff0c;left view为内容区域&#xff0c;right view为操作按钮&a…

Python学习:因为爱所以学

python的概念 Python是一种通用、高级、解释性的编程语言&#xff0c;最初由Guido van Rossum于1991年设计并开发。Python具有简单直观的语法结构&#xff0c;易于学习和阅读&#xff0c;被广泛应用于多个领域&#xff0c;包括软件开发、数据科学、人工智能等。 以下是Python的…

2024蓝桥杯每日一题(归并排序)

一、第一题&#xff1a;火柴排队 解题思路&#xff1a;归并排序 重点在于想清楚是对哪个数组进行归并排序求逆序对 【Python程序代码】 from math import * n int(input()) a list(map(int,input().split())) b list(map(int,input().split())) na,nb [],[] for …

java常用排序算法——二分查找(折半查找)概述

前言&#xff1a; 普通查找指的是把需要查找的数和数组中的数依次对应&#xff0c;直到找到该数字。但如果数据庞大&#xff0c;则会非常耗时间&#xff0c;降低性能&#xff0c;所以二分查找是一个好方法&#xff0c;记录下二分查找的使用心得。打好基础&#xff0c;daydayup!…

LCR 179. 查找总价格为目标值的两个商品 - 力扣

1. 题目 购物车内的商品价格按照升序记录于数组 price。请在购物车中找到两个商品的价格总和刚好是 target。若存在多种情况&#xff0c;返回任一结果即可。 2. 示例 3. 分析 我们首先想到暴力解法&#xff0c;这道题目的暴力还是比较简单的&#xff0c;列举每个数的情况即可…

【嵌入式】字体极限瘦身术:Fontmin在嵌入式UI中的魔法应用(附3500常用汉字)

1. 概述 在嵌入式系统的用户界面&#xff08;UI&#xff09;设计中&#xff0c;字体的选择和优化至关重要。一个恰当的字体不仅能够提升用户体验&#xff0c;还能彰显产品特色。然而&#xff0c;由于嵌入式设备常常受限于存储空间和处理能力&#xff0c;大型字体文件可能成为性…

HTML 学习笔记(四)图片

<!--通过图片标签"<img src "图片路径">"来调用图片在网页中进行显示--> <!DOCTYPE html> <html lang"en"><head><meta charset"UTF-8"><meta name"viewport" content"widthd…

基于Leatlet标注Geojson下载器实现

在上一篇文章中&#xff0c;我们学习了Leaflet的基础知识&#xff0c;包括如何创建地图、添加图层等。在本文中&#xff0c;我们将深入学习Leaflet中标注的创建和管理&#xff0c;包括如何添加标注、自定义标注图标、创建图层组、批量添加和删除标注、为标注添加属性和弹出框等…

Spring Boot工作原理

Spring Boot Spring Boot 基于 Spring 开发&#xff0c;Spirng Boot 本身并不提供 Spring 框架的核心特性以及扩展功能&#xff0c;只是用于快速、敏捷地开发新一代基于 Spring 框架的应用程序。也就是说&#xff0c;它并不是用来替代 Spring 的解决方案&#xff0c;而是和 Spr…

HTML5基础2

drag 可以把拖放事件拆分成4个步骤 设置元素为可拖放。为了使元素可拖动&#xff0c;把 draggable 属性设置为 true 。 <img draggable"true"> 拖动什么。ondragstart 和 setData() const dragestart (ev)>{ev.dataTransfer.setData(play,ev.target.id)} …

码垛【FB块】

转载&#xff1a; FUNCTION BLOCK 码垛 VAR INPUT 当前数:INT; 点l:Point; 点2:Point; X行数:REAL; Y列数:REAL; 2层数:REAL; END VAR VAR OUTPUT 目标点:Point; 点数量:INT; END VAR VAR // X差值:点2.x-点1.x; IF X行数>1 AND X差值<>0 THEN X间隔:X差值/(X行数-1)…

vue结合vue-electron创建应用程序

这里写自定义目录标题 安装electron第一种方式&#xff1a;vue init electron-vue第二种方式&#xff1a;vue add electron-builder 启动electron调试功能&#xff1a;background操作和使用1、覆盖窗口的菜单上下文、右键菜单2、监听关闭事件、阻止默认行为3、创建悬浮窗口4、窗…

2024想要赚点小钱真的很容易!帮你们找的10个搞钱第二职业

我们都希望在空闲时间里增加一些额外收入&#xff0c;并有机会找到自己热爱的事业&#xff0c;每天贝兼几十上百元是一个不错的开始&#xff0c;小钱也是钱&#xff0c; 搞钱的经验会积少成多。今天分享10个搞钱第二职业&#xff0c;2024想要赚点小钱真的很容易。 一.摆摊卖花 …

计算机找不到msvcr120.dll的五种修复方法,轻松搞定msvcr120.dll丢失问题

当计算机系统中msvcr120.dll文件丢失时&#xff0c;可能会引发一系列运行问题和故障现象。msvcr120.dll是Microsoft Visual C Redistributable Package的一部分&#xff0c;对于许多Windows应用程序的正常运行至关重要。由于msvcr120.dll是许多软件在运行过程中依赖的重要动态链…

blender怎么导入stl格式文件?

stl格式&#xff0c;一般是用来3D打印用的文件&#xff0c;这种模型一般很小&#xff0c;经常做来做一些DIY的配件&#xff0c;如下图&#xff0c;一共有七八个模型&#xff0c;3D打印机把每个模型实体打出来后&#xff0c;就可以给小朋友组装当智益玩具玩了&#xff0c;我们把…

前端面试练习24.3.8

防抖和节流 防抖&#xff08;Debouncing&#xff09;&#xff1a; 防抖是指在短时间内连续触发同一事件时&#xff0c;只执行最后一次触发的事件处理函数。 在实际应用中&#xff0c;常常用于处理用户输入的搜索框或者滚动事件。例如&#xff0c;当用户连续输入搜索关键词时&am…