【Spring Boot 源码学习】BootstrapRegistryInitializer 详解

Spring Boot 源码学习系列

在这里插入图片描述

BootstrapRegistryInitializer 详解

  • 引言
  • 往期内容
  • 主要内容
    • 1. 初识 BootstrapRegistryInitializer
    • 2. 加载 BootstrapRegistryInitializer
    • 3. BootstrapRegistryInitializer 的初始化
  • 总结

引言

书接前文《初识 SpringApplication》,我们从 Spring Boot 的启动类 SpringApplication 上入手,了解了 SpringApplication 实例化过程。其中,有如下三块内容还未详细分析:
在这里插入图片描述
本篇博文就主要围绕 2.3 的内容展开,详细分析一下加载并初始化 BootstrapRegistryInitializer 及其相关的类的逻辑。

在这里插入图片描述

往期内容

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

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 源码 均来自版本 2.7.9,其他版本有所出入,可自行查看源码。

1. 初识 BootstrapRegistryInitializer

废话不多说,我们直接来看 BootstrapRegistryInitializer 接口的源码:

@FunctionalInterface
public interface BootstrapRegistryInitializer {void initialize(BootstrapRegistry registry);
}

阅读上述代码,可以看到 BootstrapRegistryInitializer 接口被 @FunctionalInterface 注解修饰。

@FunctionalInterfaceJava 8 中引入的一个注解,用于标识一个函数式接口。函数式接口是只有一个抽象方法的接口,常用于实现 Lambda 表达式和方法引用。
使用 @FunctionalInterface 注解可以向编译器指示该接口是一个函数式接口,从而在编译时进行类型检查,确保该接口 只包含一个抽象方法。此外,该注解还可以为函数式接口生成特殊的方法,如默认方法(default method)和 静态方法(static method),这些方法可以在接口中提供更多的功能,这里就不赘述了,感兴趣的朋友可以自行查阅相关函数式接口的资料。

BootstrapRegistryInitializer 接口只定义了一个 initialize 方法,该方法只有一个参数是 BootstrapRegistry

BootstrapRegistry 是一个简单的对象注册表,它在启动和环境后处理期间都可用,直到ApplicationContext 准备好为止。它可用于注册可能创建成本较高或在 ApplicationContext 可用之前需要共享的实例。它的一个默认实现是 DefaultBootstrapContext ,后面我们会看到。

注册表使用 Class 作为键,这意味着每个给定类型只能存储一个实例。

addCloseListener(ApplicationListener) 方法可用于添加监听器,当 BootstrapContext 已关闭并且 ApplicationContext 完全准备好时,该监听器可以执行操作。例如,一个实例可能选择将自己注册为常规的 Spring bean,以便应用程序可以使用它。

简而言之,BootstrapRegistry 是一个用于存储和共享对象的注册表,这些对象在ApplicationContext 准备好之前就可能已经被创建并需要被共享。

Spring Cloud Config 中,客户端通过向配置中心(Config Server)发送请求来获取应用程序的配置信息。而 BootstrapRegistryInitializer 就是负责将配置中心的相关信息注册到 Spring 容器中的。

2. 加载 BootstrapRegistryInitializer

this.bootstrapRegistryInitializers = new ArrayList<>(getSpringFactoriesInstances(BootstrapRegistryInitializer.class));

上述代码是 SpringApplication 的核心构造方法中的逻辑,它用于加载实现了 BootstrapRegistryInitializer 接口的类。

我们进入 getSpringFactoriesInstances 方法,查看如下:

在这里插入图片描述

我们看到了如下的代码 :

SpringFactoriesLoader.loadFactoryNames(type, classLoader);

这里是通过 SpringFactoriesLoader 类的 loadFactoryNames 方法来获取 META-INF/spring.factories 中配置 key 为 BootstrapRegistryInitializer 的数据;

当然这些配置不在 Spring BootMETA-INF/spring.factories 中,我们上面提到 Spring Cloud Config 就是用 BootstrapRegistryInitializer 将配置中心的相关信息注册到 Spring 容器中,那我们就来看看 Spring Cloud Config 相关的配置。

如下是 Spring Cloud ConfigStarter 依赖:

<dependency><groupId>org.springframework.cloud</groupId><artifactId>spring-cloud-starter-config</artifactId><version>4.0.4</version>
</dependency>

导入上述依赖之后,相关的 META-INF/spring.factories 配置,我们发现是在如下的 jar 包里面【spring-cloud-config-client-4.0.4.jar】:

在这里插入图片描述

查看 META-INF/spring.factories 配置文件,我们可以看到如下:

在这里插入图片描述

# Spring Boot BootstrapRegistryInitializers
org.springframework.boot.BootstrapRegistryInitializer=\
org.springframework.cloud.config.client.ConfigClientRetryBootstrapper

有关 Spring Cloud Config 的内容,这里就不展开介绍了,感兴趣的小伙伴自行查阅 Spring Cloud Config 的官方文档。

3. BootstrapRegistryInitializer 的初始化

这里我们需要查看 SpringApplicationrun(String... args) 方法,如下所示:

在这里插入图片描述

在上述的 createBootstrapContext 方法中,就对 BootstrapRegistryInitializer 进行初始化,我们继续往下看:

在这里插入图片描述

从上图中,我们可以看到这样一行代码:

this.bootstrapRegistryInitializers.forEach((initializer) -> initializer.initialize(bootstrapContext));

这里涉及如下的知识点:

  • this.bootstrapRegistryInitializers.forEach() : Java 8Stream API,它用于遍历列表中的每个元素,并执行给定的操作【即 initializer.initialize(bootstrapContext) 】。
  • (initializer) -> initializer.initialize(bootstrapContext)Lambda 表达式,这是 Java 8 引入的一个新特性,允许以更简洁的方式表示匿名方法。它表示一个接受BootstrapRegistryInitializer 类型参数 initializer,并调用其 initialize(bootstrapContext) 方法的功能。

简而言之,对于 this.bootstrapRegistryInitializers 列表中的每个 BootstrapRegistryInitializer,使用当前的 bootstrapContext 初始化它。这里的 bootstrapContext 其实就是 BootstrapRegistry 注册表的一个默认实现 DefaultBootstrapContext

从上述的 SpringApplicationrun(String... args) 方法源码中,我们也可以看出 BootstrapRegistryInitializer 的初始化是在 Spring Boot 应用启动一开始进行的。

我们通过实现 BootstrapRegistryInitializer 接口并定义 initialize 方法,可以将自定义的 Bean 初始化器注册到 ApplicationContext 中。这样,在 Spring Boot 应用启动时,这些初始化器会被自动加载并执行,从而完成一些必要的初始化配置。

总结

本篇 Huazie 带大家详细分析了加载并初始化 BootstrapRegistryInitializer 的逻辑,这对于后续的 SpringApplication 运行流程的理解至关重要。

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

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

相关文章

谈一谈大小端

文章目录 一&#xff0c;什么是大小端二&#xff0c;为什么有大小端三&#xff0c;怎么验证大小端 一&#xff0c;什么是大小端 大端存储模式&#xff1a;是指数据的地位存储在高地址处&#xff0c;数据的高位存储在低地址处。 小端存储模式&#xff1a;是指数据的低位存储在低…

从0开始学习JavaScript--JavaScript 单例模式

单例模式是一种常见的设计模式&#xff0c;它保证一个类仅有一个实例&#xff0c;并提供一个全局访问点。在 JavaScript 中&#xff0c;单例模式通常用于创建唯一的对象&#xff0c;以确保全局只有一个实例。本文将深入探讨单例模式的基本概念、实现方式&#xff0c;以及在实际…

矩阵代数与MATLAB实现(特征值、广义特征值、酋矩阵、)

矩阵代数的相关知识 目录 一、特征值与特征向量 1、特征值与特征向量 2、MATLAB计算 二、广义特征值与广义特征向量 1、广义特征值与广义特征向量 2、MATLAB计算 三、酋矩阵 1、酋矩阵 2、MATLAB计算 四、未完待续 总结 提示&#xff1a;以下是本篇文章正文内容&…

Pytorch从零开始实战11

Pytorch从零开始实战——ResNet-50V2算法实战 本系列来源于365天深度学习训练营 原作者K同学 文章目录 Pytorch从零开始实战——ResNet-50V2算法实战环境准备数据集模型选择开始训练可视化总结 环境准备 本文基于Jupyter notebook&#xff0c;使用Python3.8&#xff0c;Pyt…

VUE语法-ref和reactive响应式数据引用

1、响应式概述 在vue中定义一个参数&#xff0c;当这个参数在使用中发生了变化&#xff0c;在页面中对这个数据应用的地方都会同步的发生变化&#xff0c;这个就是数据响应式。 2、创建一个非响应式的参数 该程序中采用的是VUE3的用法&#xff1a; 1、在程序中定义了一个局…

GraphCast:基于机器学习的全球中期天气预测模型

文章信息 文章题为”GraphCast: Learning skillful medium-range global weather forecasting”&#xff0c;该文章于2023年发表至Science&#xff0c;文章内容主要关于利用机器学习模型&#xff0c;实现高效、准确的全球中期天气预测。由于文章内容较多&#xff0c;本文仅对研…

力扣刷题篇之分治

系列文章目录 目录 系列文章目录 前言 一、分解问题 二、解决子问题 三、合并结果 总结 前言 刷题按照&#xff1a; [力扣刷题攻略] Re&#xff1a;从零开始的力扣刷题生活 - 力扣&#xff08;LeetCode&#xff09; 参考&#xff1a; 「五大常用算法」一文搞懂分治算法…

大数据HCIE成神之路之数学(4)——最优化实验

最优化实验 1.1 最小二乘法实现1.1.1 算法介绍1.1.2 代码实现1.2 梯度下降法实现1.2.1 算法介绍1.2.2 代码实现1.3 拉格朗日乘子法1.3.1 实验1.3.2 实验操作步骤1.1 最小二乘法实现 1.1.1 算法介绍 最小二乘法(Least Square Method),做为分类回归算法的基础,有着悠久的历…

第20章:多线程

20.1 线程简介 在Java中&#xff0c;并发机制非常重要&#xff0c;程序员可以在程序中执行多个线程&#xff0c;每个线程完成一个功能&#xff0c;并与其他线程并发执行&#xff0c;这种机制被称为多线程。但是&#xff0c;并不是所有编程语言都支持多线程。 线程的特点&#…

visual studio 2022 更改字体和大小

工具--->选项 文本编辑器 输出窗口

Linux系统之uptime命令的基本使用

Linux系统之uptime命令的基本使用 一、uptime介绍二、uptime命令使用帮助2.1 uptime的help帮助信息2.2 uptime的语法解释 三、uptime的基本使用3.1 直接使用uptime命令3.2 显示uptime版本信息3.3 显示系统运行时间3.4 显示系统最后一次启动时间 四、uptime命令的使用注意事项 一…

基于YOLOv8深度学习的生活垃圾分类目标检测系统【python源码+Pyqt5界面+数据集+训练代码】目标检测

《博主简介》 小伙伴们好&#xff0c;我是阿旭。专注于人工智能、AIGC、python、计算机视觉相关分享研究。 ✌更多学习资源&#xff0c;可关注公-仲-hao:【阿旭算法与机器学习】&#xff0c;共同学习交流~ &#x1f44d;感谢小伙伴们点赞、关注&#xff01; 《------往期经典推…

C++前缀和算法的应用:优化了6版的1324模式

本文涉及的基础知识点 C算法&#xff1a;前缀和、前缀乘积、前缀异或的原理、源码及测试用例 包括课程视频 本题其它解法 C前缀和算法的应用&#xff1a;统计上升四元组 类似题解法 包括题目及代码C二分查找算法&#xff1a;132 模式解法一枚举3C二分查找算法&#xff1a;…

k8s中Pod控制器简介,ReplicaSet、Deployment、HPA三种处理无状态pod应用的控制器介绍

目录 一.Pod控制器简介 二.ReplicaSet&#xff08;简写rs&#xff09; 1.简介 &#xff08;1&#xff09;主要功能 &#xff08;2&#xff09;rs较完整参数解释 2.创建和删除 &#xff08;1&#xff09;创建 &#xff08;2&#xff09;删除 3.扩容和缩容 &#xff08…

vuepress-----7、发布在GitHub

# 7、发布在GitHub 在你的项目中&#xff0c;创建一个如下的 deploy.sh 文件&#xff08;请自行判断去掉高亮行的注释&#xff09;: #!/usr/bin/env sh# 确保脚本抛出遇到的错误 set -e# 生成静态文件 npm run docs:build# 进入生成的文件夹 cd docs/.vuepress/dist# 如果是发…

WebUI自动化学习(Selenium+Python+Pytest框架)004

接下来&#xff0c;WebUI基础知识最后一篇。 1.下拉框操作 关于下拉框的处理有两种方式 &#xff08;1&#xff09;按普通元素定位 安装普通元素的定位方式来定位下拉框&#xff0c;使用元素的操作方法element.click()方法来操作下拉框内容的选择 &#xff08;2&#xff09…

PCB设计注意事项

四个二极管不能省略 pwm波跟电机频率不要是倍频 运放越靠近取样电阻越好 反向输入端跟输出端很敏感&#xff0c;有寄生电容就容易震荡 距离取样电阻近就会距离单片机远&#xff0c;那么线上会有寄生电容&#xff0c;这时候在输出端接一个10k电阻到地

深度学习-模型调试经验总结

1、 这句话的意思是&#xff1a;期望张量的后端处理是在cpu上&#xff0c;但是实际是在cuda上。排查代码发现&#xff0c;数据还在cpu上&#xff0c;但是模型已经转到cuda上&#xff0c;所以可以通过把数据转到cuda上解决。 解决代码&#xff1a; tensor.to("cuda")…

Redis 入门和环境搭建

认识Redis Redis是一种NoSQL数据库&#xff0c;以键值对形式存储数据&#xff0c;支持多种数据结构&#xff0c;包括字符串、哈希、列表、集合、有序集合等&#xff0c;使其适用于多种应用场景。由于所有数据都存储在内存中&#xff0c;Redis的读写性能非常高。同时&#xff0…

安网AC智能路由系统actpt_5g.data敏感信息泄露漏洞复现 [附POC]

文章目录 安网AC智能路由系统actpt_5g.data敏感信息泄露漏洞复现 [附POC]0x01 前言0x02 漏洞描述0x03 影响版本0x04 漏洞环境0x05 漏洞复现1.访问漏洞环境2.构造POC3.复现 安网AC智能路由系统actpt_5g.data敏感信息泄露漏洞复现 [附POC] 0x01 前言 免责声明&#xff1a;请勿利…