Spring Boot 深入剖析:BootstrapRegistry 与 BeanDefinitionRegistry 的对比

在 Spring Boot 的启动过程中,BootstrapRegistry 和 BeanDefinitionRegistry 是两个名为“Registry”却扮演着截然不同角色的核心接口。理解它们的差异是深入掌握 Spring Boot 启动机制和进行高级定制开发的关键。

BootstrapRegistry 

	public static ConfigurableApplicationContext run(Class<?>[] primarySources, String[] args) {return new SpringApplication(primarySources).run(args);}

当我们查看SpringBoot的启动方法的源码,我们发现run方法的源码本质上是初始化了一个SpringApplication对象随后调用其run方法来执行。我们点击进去这个SpringApplication的构造方法中我们看到

	public SpringApplication(ResourceLoader resourceLoader, Class<?>... primarySources) {this.resourceLoader = resourceLoader;Assert.notNull(primarySources, "PrimarySources must not be null");this.primarySources = new LinkedHashSet<>(Arrays.asList(primarySources));this.webApplicationType = WebApplicationType.deduceFromClasspath();this.bootstrapRegistryInitializers = new ArrayList<>(getSpringFactoriesInstances(BootstrapRegistryInitializer.class));setInitializers((Collection) getSpringFactoriesInstances(ApplicationContextInitializer.class));setListeners((Collection) getSpringFactoriesInstances(ApplicationListener.class));this.mainApplicationClass = deduceMainApplicationClass();}

在SpringApplication这个构造方法初始化了两个类分别是BootstrapRegistryInitializer和ApplicationContextInitializer,这两个接口都是只有一个方法initialize,他们的作用则是分别对applicationContext和BootstrapRegistry来进行预处理,而BootstrapRegistry的作用则是体现在:当你需要创建一个 ApplicationContextInitializer 来定制应用上下文,但这个Initializer的逻辑依赖于一个特定的组件(例如,一个高级的 Decryptor 解密器用来解密数据库密码)。然而,这个 Decryptor 本身又可能依赖于Spring的环境配置(Environment),而 Environment 又是在ApplicationContext创建过程中才被完全初始化的。

这就形成了一个 启动阶段的循环依赖

  • 想创建 ApplicationContext → 需要先执行 ApplicationContextInitializer

  • 想执行 ApplicationContextInitializer → 需要先有 Decryptor 实例

  • 想创建 Decryptor 实例 → 又需要 Environment(它又来自于 ApplicationContext

BootstrapRegistry 的解决方案:
BootstrapRegistry 允许你在一切开始之前(在任何一个 ApplicationContextInitializer 执行之前),就通过 BootstrapRegistryInitializer 将像 Decryptor 这样的关键组件作为完全实例化的对象注册到一个临时的“工具箱”里。

因此BootstrapRegistry 是启动引导器,负责在最前期提供现成的工具实例。

BeanDefinitionRegistry 

对于BeanDefinitionRegistry 的实例化则是在BeanDefinitionRegistryPostProcessor的处理类当中的postProcessBeanDefinitionRegistry来对其进行实例化处理的。

  • 角色IoC 容器的建筑师

  • 定位:它是 Spring Framework 中 ApplicationContext 的核心接口,负责持有所有 Bean 的“蓝图”(BeanDefinition)。ApplicationContext 会根据这些蓝图来实例化、组装和管理所有的Bean。它是Spring IoC容器的心脏。它定义了应用程序中所有组件的基本信息,但并不负责实例化,而是为后续的实例化、依赖注入提供元数据。它是正式舞台的后台策划

也就是说当前容器内的bean所有信息都会放到BeanDefinitionRegistry 中来进行处理,BootstrapRegistry 的生命周期早于 BeanDefinitionRegistry。前者为后者的初始化过程提供支持,通常通过 ApplicationContextInitializer 将 BootstrapRegistry 中的实例“转移”或“注册”到 BeanDefinitionRegistry 中,使其成为被IoC容器管理的正式Bean

详细对比

维度BeanDefinitionRegistryBootstrapRegistry
所属阶段ApplicationContext 阶段 (主阶段)Bootstrap 阶段 (极早期)
核心目的注册Bean的定义信息 (BeanDefinition),即如何创建Bean的蓝图注册和持有完全实例化的对象实例,为引导过程提供现成的工具
注册内容BeanDefinition 对象(包含类名、作用域、属性值、初始化方法等元数据)。任何类型的对象实例 (如 RestTemplateDecryptor)。通过 Supplier 或 BootstrapRegistry.InstanceSupplier 延迟提供。
生命周期持久。与 ApplicationContext 同生命周期,伴随整个应用运行。短暂。仅在 Bootstrap 阶段有效。一旦 ApplicationContext 准备就绪,其使命基本完成,内容可被转移到正式容器中。
接口方法registerBeanDefinition(String beanName, BeanDefinition beanDefinition)
removeBeanDefinition(String beanName)
getBeanDefinition(String beanName)
register(Class<T> type, BootstrapRegistry.InstanceSupplier<T> instanceSupplier)
register(Class<T> type, Supplier<T> supplier)
isRegistered(Class<T> type)
依赖解决解决 Bean之间的循环依赖(通过三级缓存机制)。解决 启动流程上的依赖问题(通过提前实例化关键对象,打破初始化顺序的僵局)。
获取方式通过 ApplicationContext (即 BeanFactory) 的 getBean() 方法获取最终Bean实例在 ApplicationContextInitializer 中,通过 BootstrapContext 的 get(Class<T> type) 方法获取预先注册的实例
典型应用注册所有由 @Component@Bean@Service 等注解定义的组件。Spring Cloud Config:在获取远端配置前注册安全的 RestTemplate
自定义引导:提前注册解密器、自定义的 PropertySourceLoader 等。
设计模式工厂模式:存储的是产品的设计图,需要时再根据图纸生产。仓库模式:直接存储了准备好的产品,需要时直接取用。

BootstrapRegistry 和 BeanDefinitionRegistry 是 Spring Boot 为解耦复杂的启动过程、清晰划分职责而设计的两个互补的组件。它们并非竞争或替代关系,而是分别在不同的生命周期阶段、为解决不同层面的问题而协同工作的伙伴。

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

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

相关文章

贪心算法应用:速率单调调度(RMS)问题详解

Java中的贪心算法应用&#xff1a;速率单调调度(RMS)问题详解 1. 速率单调调度(RMS)概述 速率单调调度(Rate Monotonic Scheduling, RMS)是一种广泛应用于实时系统中的静态优先级调度算法&#xff0c;属于贪心算法在任务调度领域的经典应用。 1.1 基本概念 RMS基于以下原则&…

Cesium4--地形(OSGB到3DTiles)

1 OSBG OSGB&#xff08;OpenSceneGraph Binary&#xff09;是基于 OpenSceneGraph&#xff08;OSG&#xff09; 三维渲染引擎的二进制三维场景数据格式&#xff0c;广泛用于存储和传输倾斜摄影测量、BIM、点云等大规模三维模型&#xff0c;尤其在国产地理信息与智慧城市项目中…

多语言共享贩卖机投资理财共享售卖机投资理财系统

多语言共享贩卖机投资理财/共享售卖机分红/充电宝/充电桩投资理财系统 采用thinkphp内核开发&#xff0c;支持注册赠金、多级分销&#xff0c;功能很基础 修复后台用户列表管理 可自定义理财商品 多种语言还可以添加任意语言 源码开源 多级分销 注册赠金等

[Windows] PDF 专业压缩工具 v3.0

[Windows] PDF 专业压缩工具 v3.0 链接&#xff1a;https://pan.xunlei.com/s/VOZwtC_5lCF-UF6gkoHuxWMoA1?pwdchg8# PDF 压缩工具 3.0 新版功能特点 - 不受页数限制&#xff01; 一、核心压缩功能 1.多模式智能压缩 支持 4 种压缩模式&#xff1a;平衡模式&#xff08…

SHEIN 希音 2026 校招 内推 查进度

SHEIN 希音 2026 校招 内推 查进度 &#x1f3e2;公司名称&#xff1a;SHEIN 希音 &#x1f4bb;招聘岗位&#xff1a;前端、后端、测试、产品、安全、运维、APP 研发、数据分析、设计师、买手、企划、招商、管培生 &#x1f31f;内推码&#xff1a;NTA2SdK &#x1f4b0;福利待…

ARM (6) - I.MX6ULL 汇编点灯迁移至 C 语言 + SDK 移植与 BSP 工程搭建

回顾一、核心关键字&#xff1a;volatile1.1 作用告诉编译器&#xff1a;被修饰的变量会被 “意外修改”&#xff08;如硬件寄存器的值可能被外设自动更新&#xff09;&#xff0c;禁止编译器对该变量进行优化&#xff08;如缓存到寄存器、删除未显式修改的代码&#xff09;。本…

Vue中使用keep-alive实现页面前进刷新、后退缓存的完整方案

Vue中使用keep-alive实现页面前进刷新、后退缓存的完整方案 在Vue单页应用中&#xff0c;路由切换时组件默认会经历完整的销毁-重建流程&#xff0c;这会导致两个典型问题&#xff1a;从搜索页跳转到列表页需要重新加载数据&#xff0c;而从详情页返回列表页又希望保留滚动位置…

Visual Studio Code 安装与更新故障排除:从“拒绝访问”到成功恢复

Visual Studio Code 安装与更新故障排除&#xff1a;从“拒绝访问”到成功恢复的实践分析 摘要&#xff1a; 本文旨在探讨 Visual Studio Code (VS Code) 在安装与更新过程中常见的故障&#xff0c;特别是涉及“拒绝访问”错误、文件缺失以及快捷方式和任务栏图标异常等问题。…

简单UDP网络程序

目录 UDP网络程序服务端 封装 UdpSocket 服务端创建套接字 服务端绑定 运行服务器 UDP网络程序客户端 客户端创建套接字 客户端绑定 运行客户端 通过上篇文章的学习&#xff0c;我们已经对网络套接字有了一定的了解。在本篇文章中&#xff0c;我们将基于之前掌握的知识…

如何解决 pip install 安装报错 ModuleNotFoundError: No module named ‘requests’ 问题

Python系列Bug修复PyCharm控制台pip install报错&#xff1a;如何解决 pip install 安装报错 ModuleNotFoundError: No module named ‘requests’ 问题 摘要 在日常Python开发过程中&#xff0c;pip install 是我们最常用的依赖安装命令之一。然而很多开发者在 PyCharm 控制台…

解释 ICT, Web2.0, Web3.0 这些术语的中文含义

要理解“ICT Web2.0”术语的中文含义&#xff0c;需先拆解为 ICT 和 Web2.0 两个核心概念分别解析&#xff0c;再结合二者的关联明确整体指向&#xff1a; 1. 核心术语拆解&#xff1a;中文含义与核心定义 &#xff08;1&#xff09;ICT&#xff1a;信息与通信技术 中文全称&am…

IDEA版本控制管理之使用Gitee

使用Gitee如果之前没用过Gitee&#xff0c;那么IDEA中应该长这样&#xff08;第一次使用&#xff09;如果之前使用过Gitee&#xff0c;那么IDEA中应该长这样这种情况&#xff0c;可以先退出Gitee&#xff0c;再拉取Gitee&#xff0c;退出Gitee方法见文章底部好&#xff0c;那么…

NLP(自然语言处理, Natural Language Processing)

让计算机能够理解、解释、操纵和生成人类语言&#xff0c;从而执行有价值的任务。 关注社区&#xff1a;Hugging Face、Papers With Code、GitHub 是现代NLP学习不可或缺的资源。许多最新模型和代码都在这里开源。 ①、安装库 pip install numpy pandas matplotlib nltk scikit…

后端json数据反序列化枚举类型不匹配的错误

后端json数据反序列化枚举类型不匹配的错误后端返回的json格式在前端反序列化报错System.Text.Json.JsonException:“The JSON value could not be converted to TodoReminderApp.Models.Priorityen. Path: $.Data.Items.$values[0].Priority | LineNumber: 0 | BytePositionIn…

市面上主流接口测试工具对比

公司计划系统的开展接口自动化测试&#xff0c;需要我这边调研一下主流的接口测试框架给后端测试&#xff08;主要测试接口&#xff09;的同事介绍一下每个框架的特定和使用方式。后端同事根据他们接口的特点提出一下需求&#xff0c;看哪个框架更适合我们。 2025最新Jmeter接口…

2025.2.4 更新 AI绘画秋葉aaaki整合包 Stable Diffusion整合包v4.10 +ComfyUI 整合包下载地址

2025.2.4 更新 AI绘画秋葉aaaki整合包 Stable Diffusion整合包v4.10 ComfyUI 整合包下载地址Stable Diffusion整合包【下载链接】ComfyUI整合包【下载链接】【报错解决】Stable Diffusion整合包 【下载链接】 下载地址 https://uwtxfkm78ne.feishu.cn/wiki/GHgVwA2LPiE9x2kj4W…

Nginx优化与 SSL/TLS配置

1、隐藏版本号可以使用Fiddler工具抓取数据包&#xff0c;查看Nginx版本&#xff0c;也可以在CentOS中使用命令curl -I http://192.168.10.23 显示响应报文首部信息。方法一&#xff1a;方法一&#xff1a;修改配置文件方式 vim /usr/local/nginx/conf/nginx.conf http {includ…

JavaWeb05

一、Listener监听器1、简介Listener是Servlet规范中的一员在Servlet中&#xff0c;所有的监听器接口都是以Listener结尾监听器实际上是Servlet规范留给JavaWeb程序员的一些特殊时机当在某些时机需要执行一段Java代码时&#xff0c;可以用对应的监听器2、常用的监听器接口&#…

科普:在Windows个人电脑上使用Docker的极简指南

在Windows个人电脑上使用Docker的极简指南&#xff1a; 1. 快速安装 下载安装包&#xff08;若进不了官网&#xff0c;则可能要科学上网&#xff09; 访问Docker Desktop官方下载页 访问Docker官网 选择Windows及&#xff08;AMD64 也称为 x86-64&#xff0c;是目前主流 PC的…

【开题答辩全过程】以 “居逸”民宿预订微信小程序为例,包含答辩的问题和答案

个人简介一名14年经验的资深毕设内行人&#xff0c;语言擅长Java、php、微信小程序、Python、Golang、安卓Android等开发项目包括大数据、深度学习、网站、小程序、安卓、算法。平常会做一些项目定制化开发、代码讲解、答辩教学、文档编写、也懂一些降重方面的技巧。感谢大家的…