【Spring Boot 源码学习】BootstrapRegistry 初始化器实现

news2024/9/24 6:25:26

《Spring Boot 源码学习系列》

在这里插入图片描述

BootstrapRegistry 初始化器实现

  • 一、引言
  • 二、往期内容
  • 三、主要内容
    • 3.1 BootstrapRegistry
    • 3.2 BootstrapRegistryInitializer
    • 3.3 BootstrapRegistry 初始化器实现
      • 3.3.1 定义 DemoBootstrapper
      • 3.3.2 添加 DemoBootstrapper
  • 四、总结

一、引言

前面的博文《BootstrapRegistryInitializer 详解》,Huazie 带大家一起详细分析了 Spring Boot 启动时加载并初始化 BootstrapRegistryInitializer 及其相关的类的逻辑。本篇就让我们自定义 BootstrapRegistryInitializer 接口实现,以此来执行自定义的初始化操作【如注册自定义的 Bean、添加 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 源码 均来自版本 2.7.9,其他版本有所出入,可自行查看源码。

3.1 BootstrapRegistry

在《BootstrapRegistry 详解》 中,Huazie 详细介绍了 BootstrapRegistry 的源码,这有助于下面介绍的 BootstrapRegistry 初始化器的实现逻辑,有不知道的朋友们直接查看即可,这里不再赘述。

3.2 BootstrapRegistryInitializer

在《BootstrapRegistryInitializer 详解》 中,Huazie 详解分析了加载并初始化 BootstrapRegistryInitializer 的逻辑,这同样有助于
理解下面将要讲解的内容,还不熟悉的朋友们赶紧花点时间了解下,这里不再赘述。

3.3 BootstrapRegistry 初始化器实现

3.3.1 定义 DemoBootstrapper

下面我们来定义一个类 DemoBootstrapper,该类实现 BootstrapRegistryInitializer 接口,如下:

public class DemoBootstrapper implements BootstrapRegistryInitializer {
    @Override
    public void initialize(BootstrapRegistry registry) {
        // 注册一些自定义的对象 或者 加载自定义的一些配置
    }
}

在《BootstrapRegistryInitializer 详解》 的 3.2 小节,Huazie 介绍了 BootstrapRegistryInitializer 的加载过程,上述我们自定义的 DemoBootstrapper 也会在 Spring Boot 启动引导阶段进行加载并初始化。

上述定义中,我们只是展示了一个空实现的类,其中的 initialize 方法还未做处理。

至于 initialize 方法中该添加哪些逻辑,这就要看它的参数 BootstrapRegistry 接口了。

下面代码,Huazie 演示了如何 注册自定义的对象,以及添加 引导上下文关闭事件监听器

// 注册 User对象,它就是一个简单的 POJO 类,含两个成员变量:名称 name 和年龄 age
registry.register(User.class, context -> new User("Huazie", 18));
// 添加 BootstrapContext关闭 监听器
registry.addCloseListener(new DemoBootstrapContextClosedListener());

DemoBootstrapContextClosedListener ,即引导上下文关闭事件监听器,相关演示代码如下:

public class DemoBootstrapContextClosedListener implements ApplicationListener<BootstrapContextClosedEvent>, Ordered {
    @Override
    public void onApplicationEvent(BootstrapContextClosedEvent event) {
        BootstrapContext bootstrapContext = event.getBootstrapContext();
        if (bootstrapContext.isRegistered(User.class)) {
            System.out.println("BootstrapContext关闭时获取User:" + bootstrapContext.get(User.class));
        }
    }

    @Override
    public int getOrder() {
        return 1;
    }
}

虽然上面添加了引导上下文关闭事件监听器,但是我们还不知道什么时候它会被执行。

DemoBootstrapContextClosedListener 中,我们看到了 BootstrapContext 的使用,显然这里涉及到了引导上下文的实际使用场景,由于篇幅受限,将在下篇介绍,大家不妨期待一下。

另外,在 DemoBootstrapContextClosedListener 中,还看到它实现了 Ordered 接口【spring-core 包中的接口】。

那么在事件监听器中,这个 Ordered 接口是用来做什么的呢?

在回答这个问题之前,我们先来看看 Ordered 接口的源码:

public interface Ordered {
	int HIGHEST_PRECEDENCE = Integer.MIN_VALUE;
	int LOWEST_PRECEDENCE = Integer.MAX_VALUE;
	int getOrder();
}

Ordered 接口定义了两个常量和一个方法:

  • HIGHEST_PRECEDENCE:最高优先级值的有用常数【最小的 Integer 值】
  • LOWEST_PRECEDENCE :最低优先级值的有用常数【最大的 Integer 值】
  • int getOrder() :获取当前对象的优先级值【值越小,优先级越高】

源码中对于 Ordered 接口是这样说的:

它可以被需要排序的对象实现,例如在集合中。实际的排序可以被解读为优先级排序,其中第一个对象(即有着最低的排序值)具有最高的优先级。

当然,Ordered 接口还有一个扩展接口,即优先级标记接口 PriorityOrderedPriorityOrdered 对象总是优先于普通 Ordered 对象,无论它们的排序值如何。当对一组 Ordered 对象进行排序时,PriorityOrdered 对象和普通 Ordered 对象实际上被视为两个独立的子集,PriorityOrdered 对象子集先于普通 Ordered 对象子集,并在这些子集内部应用相对排序。

上述排序逻辑请查看 spring-core 包中的 AnnotationAwareOrderComparator 类 和 OrderComparator 类,这里不再赘述了。

现在可以回答上面的问题了:在事件监听器中实现 Ordered 接口,可以用来确保 多个监听同一事件的监听器 可以按照我们 预定的顺序执行

3.3.2 添加 DemoBootstrapper

不过,要想能够加载到自定义的 DemoBootstrapper ,我们还需要将它添加到 bootstrapRegistryInitializers 中才可以。

// SpringApplication的私有变量
private List<BootstrapRegistryInitializer> bootstrapRegistryInitializers;

那么,我们该如何添加呢?

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

  • META-INF/spring.factories 中添加 org.springframework.boot.BootstrapRegistryInitializer 的配置。这种方式,我们从 《BootstrapRegistryInitializer 详解》 的 3.2 小节可见一斑。

    org.springframework.boot.BootstrapRegistryInitializer=com.example.demo.DemoBootstrapper
    
  • 通过 SpringApplication 中的 addBootstrapRegistryInitializer 方法添加。其实这里在笔者的《SpringApplication 的定制化介绍》中的 1.5 小节也提及过。

    SpringApplication springApplication = new SpringApplication(DemoApplication.class);
    springApplication.addBootstrapRegistryInitializer(new DemoBootstrapper());
    // 其他省略。。。
    

四、总结

本篇 Huazie 介绍了如何自定义 BootstrapRegistry 初始化器实现,其中演示如何在引导上下文中注册了自定义的对象以及如何在引导上下文中添加引导上下文关闭事件监听器

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

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

相关文章

反序列化逃逸 [安洵杯 2019]easy_serialize_php1

打开题目 题目源码&#xff1a; <?php$function $_GET[f];function filter($img){$filter_arr array(php,flag,php5,php4,fl1g);$filter /.implode(|,$filter_arr)./i;return preg_replace($filter,,$img); }if($_SESSION){unset($_SESSION); }$_SESSION["user&qu…

2024年腾讯云优惠政策_腾讯云TOP10优惠活动

腾讯云服务器多少钱一年&#xff1f;62元一年起&#xff0c;2核2G3M配置&#xff0c;腾讯云2核4G5M轻量应用服务器218元一年、756元3年&#xff0c;4核16G12M服务器32元1个月、312元一年&#xff0c;8核32G22M服务器115元1个月、345元3个月&#xff0c;腾讯云服务器网txyfwq.co…

医学大数据|文献阅读|有关“胃癌+机器学习”的研究记录

目录 1.基于32基因特征构建的机器学习模型可有效预测胃癌患者的预后和治疗反应 2.胃癌患者术后90天死亡率的机器学习风险预测模型 3.使用机器学习模型预测幽门螺杆菌根除患者胃癌患病风险 4.利用初始内窥镜检查和组织学结果进行个性化胃癌发病率预测 1.基于32基因特征构建的…

马斯克指控OpenAI违背成立协议,要求恢复开源;Automattic否认向AI公司出售用户数据

&#x1f989; AI新闻 &#x1f680; 马斯克指控OpenAI违背成立协议&#xff0c;要求恢复开源 摘要&#xff1a;马斯克近日在旧金山高等法院对OpenAI及其CEO阿尔特曼提起诉讼&#xff0c;指控他们违反最初促进AI技术造福人类非营利方向的成立协议。马斯克声称&#xff0c;Ope…

租房招聘平台新篇章:Java+SpringBoot技术革新

✍✍计算机毕业编程指导师 ⭐⭐个人介绍&#xff1a;自己非常喜欢研究技术问题&#xff01;专业做Java、Python、微信小程序、安卓、大数据、爬虫、Golang、大屏等实战项目。 ⛽⛽实战项目&#xff1a;有源码或者技术上的问题欢迎在评论区一起讨论交流&#xff01; ⚡⚡ Java、…

探索数据结构:深入了解顺序表的奥秘

✨✨ 欢迎大家来到贝蒂大讲堂✨✨ &#x1f388;&#x1f388;养成好习惯&#xff0c;先赞后看哦~&#x1f388;&#x1f388; 所属专栏&#xff1a;数据结构与算法 贝蒂的主页&#xff1a;Betty’s blog 1. 什么是顺序表 顺序表是用一段物理地址连续的存储单元依次存储数据元…

购买腾讯云服务器请先领取代金券,2024腾讯云优惠

腾讯云优惠代金券领取入口共三个渠道&#xff0c;腾讯云新用户和老用户均可领取8888元代金券&#xff0c;可用于云服务器等产品购买、续费和升级使用&#xff0c;阿腾云atengyun.com整理腾讯云优惠券&#xff08;代金券&#xff09;领取入口、代金券查询、优惠券兑换码使用方法…

C++真题列表

题目解析&#xff1a;RAM是闪存&#xff0c;只要一关机一拔电&#xff0c;就会丢失数据 题目解答&#xff1a;A 题目解析&#xff1a;TXT格式是文本文档 题目解答&#xff1a;B 题目解析&#xff1a;IP地址中每一个字节的取值范围是[0~255]&#xff0c;是不可能有256的 题目…

完美解决Iframe嵌入帆软报表出现跨域cookie写不进去的问题

随着google chrome对第三方cookie的限制越来越狠,现在发现之前使用iframe嵌入的帆软报表已经不好使了。官方现在解决iframe嵌入帆软报表出现跨域导致cookie写不进去的方案是主推 统一主域名的方案(谷歌浏览器单点登录失败- FineReport帮助文档 - 全面的报表使用教程和学习资料…

java 基础(核心知识搭配代码)

前言 java的学习分为了上部分以及下部分进行学习&#xff0c;上部分就是对于java的基础知识&#xff0c;面向对象上&#xff0c;面向对象下&#xff0c;异常操作&#xff0c;javaApi&#xff1b;下部主要是集合&#xff0c;泛型&#xff0c;反射&#xff0c;IO流&#xff0c;J…

【HTML】HTML基础5(特殊字符)

目录 特殊字符的作用 常用的特殊字符 使用效果 特殊字符的作用 例如 当我在两个文字间打出空格时 <p>“银河护卫队”系列 在漫威电影宇宙中一直是异数般的存在&#xff0c;不仅因为影片主角是一群反英雄&#xff0c;<strong>与超级英雄相比显得格格不入<…

Ubuntu18.04安装RTX2060显卡驱动+CUDA+cuDNN

Ubuntu18.04安装RTX2060显卡驱动CUDAcuDNN 1 安装RTX2060显卡驱动1.1 查看当前显卡是否被识别1.2 安装驱动依赖1.3 安装桌面显示管理器1.4 下载显卡驱动1.5 禁用nouveau1.6 安装驱动1.7 查看驱动安装情况 2 安装CUDA2.1 查看当前显卡支持的CUDA版本2.2 下载CUDA Toolkit2.3 安装…

41、网络编程/TCP.UDP通信模型练习20240301

一、编写基于TCP的客户端实现以下功能&#xff1a; 通过键盘按键控制机械臂&#xff1a;w(红色臂角度增大)s&#xff08;红色臂角度减小&#xff09;d&#xff08;蓝色臂角度增大&#xff09;a&#xff08;蓝色臂角度减小&#xff09;按键控制机械臂 1.基于TCP服务器的机械臂…

【办公类-21-05】20240227单个word按“段落数”拆分多个Word(成果汇编 只有段落文字 1拆5)

作品展示 背景需求 前文对一套带有段落文字和表格的word进行13份拆分 【办公类-21-04】20240227单个word按“段落数”拆分多个Word&#xff08;三级育婴师操作参考题目1拆13份&#xff09;-CSDN博客文章浏览阅读293次&#xff0c;点赞8次&#xff0c;收藏3次。【办公类-21-04…

多余图片人物有什么办法可以去掉?一分钟教你搞定

在我们的快节奏生活中&#xff0c;旅游已经成为了一种宝贵的放松方式&#xff0c;它让我们有机会暂时逃离日常的喧嚣&#xff0c;感受大自然的宁静与美丽。每一次踏足新的土地&#xff0c;我们都会被各种独特的风景所吸引&#xff0c;从雄伟的山川到细腻的街景&#xff0c;每一…

市场占比不足1.5%,折叠屏手机为何香不起来?

2007年&#xff0c;取消了实体按键键盘的iPhone诞生&#xff0c;不到四年的时间&#xff0c;就将诺基亚变成了历史。依靠率先发起的触屏技术&#xff0c;苹果快速抢占了全球智能手机市场&#xff0c;并掀起了智能机迭代的潮流。 但折叠屏手机显然没那么幸运。2018年&#xff0…

AcWing 788. 逆序对的数量 解题思路及代码

先贴个题目&#xff1a; 以及原题链接&#xff1a; 788. 逆序对的数量 - AcWing题库https://www.acwing.com/problem/content/790/ 这题也是板子题&#xff0c;就是对归并排序的衍生&#xff0c;我们先分析下如果用归并排序对排序区间进行二分的话&#xff0c;逆序对可能出现的…

【DAY07 软考中级备考笔记】数据结构:线性结构,数组矩阵和广义表

数据结构&#xff1a;线性结构&#xff0c;数组矩阵和广义表 3月2日 – 天气&#xff1a;晴 1. 线性表的定义和存储方式 > 这一部分只需要掌握下面的两点即可&#xff1a; > > * 采用顺序存储和链式存储的特点 > * 单链表的插入和删除操作 2. 栈和队列 > 这里需…

antvX6 - Vue自定义节点,并实现多种画布操作,拖拽、缩放、连线、双击、检索等等

一、 首先 antv x6 分为两个版本 低版本和高版本 我这里是使用的2.0版本 并且搭配了相关插件 例如&#xff1a;画布的图形变换、地图等 个人推荐 2.0版本&#xff0c;高版本配置多&#xff0c;可使用相关插件多&#xff0c;但是文档描述小&#xff0c;仍在更新&#xff0c; 低…