spring5.1+SmartInstantiationAwareBeanPostProcessor 解决循环依赖
SmartInstantiationAwareBeanPostProcessor 解决循环依赖的过程, 例如上面的 A依赖B, B依赖A
SmartInstantiationAwareBeanPostProcessor 是 Spring 中的一个接口,它扩展了 InstantiationAwareBeanPostProcessor 接口并提供了对 Bean 的实例化和属性填充的更高级的控制。在 Spring Boot 项目中,SmartInstantiationAwareBeanPostProcessor 通过三级缓存机制解决了循环依赖的问题。以 A 依赖 B,B 依赖 A 为例,我们来了解下这个过程:
-
当容器开始实例化 A 时,首先会调用 SmartInstantiationAwareBeanPostProcessor#predictBeanType 方法来预测 Bean 的类型。如果可以预测到类型,Spring 会优先使用这个类型来实例化对象。
-
接下来会调用 SmartInstantiationAwareBeanPostProcessor#getEarlyBeanReference 方法获取 A 的提前暴露的引用。这个引用通常是一个代理对象,它可以处理 A 对 B 的依赖。
-
将 A 的提前暴露引用放入三级缓存。三级缓存分别是 singletonObjects、earlySingletonObjects 和 singletonFactories。其中,singletonObjects 用于存放完全初始化好的单例 Bean,earlySingletonObjects 用于存放提前暴露的 Bean 引用,singletonFactories用于存放原始 Bean 的工厂对象。在这个例子中,A 的提前暴露引用会被放入 earlySingletonObjects 缓存。
-
接下来,容器开始实例化 B。同样地,会调用 SmartInstantiationAwareBeanPostProcessor#predictBeanType 和 SmartInstantiationAwareBeanPostProcessor#getEarlyBeanReference 方法获取 B 的提前暴露引用,并将其放入 earlySingletonObjects 缓存。
-
当 B 的实例化完成后,开始填充属性。这时会发现 B 依赖 A,于是会从三级缓存中获取 A 的引用。由于 A 正在创建过程中,所以从 earlySingletonObjects 缓存中获取到了 A 的提前暴露引用。将 A 的引用设置到 B 的属性上,完成 B 的属性填充。
-
B 的实例化和属性填充完成后,将 B 从 earlySingletonObjects 移动到 singletonObjects 缓存中。
-
接下来,开始填充 A 的属性。由于 A 依赖 B,会从三级缓存中获取 B 的引用。此时,B 已经完全初始化完成,所以从 singletonObjects 缓存中获取到了 B 的引用。将 B 的引用设置到 A 的属性上,完成 A 的属性填充。
-
A 的实例化和属性填充完成后,将 A 从 earlySingletonObjects 移动到 singletonObjects 缓存中。至此,A 和 B 的循环依赖解决了。
-
容器会继续调用各个 BeanPostProcessor 的 postProcessAfterInitialization 方法,对 A 和 B 进行后置处理。这些后置处理可能包括代理对象的创建等操作。
-
最后,A 和 B 的实例化和属性填充完成,循环依赖被成功解决。容器将 A 和 B 的引用提供给其他需要它们的 Bean。
通过以上流程,Spring Boot 利用 SmartInstantiationAwareBeanPostProcessor 和三级缓存机制成功地解决了 A 和 B 之间的循环依赖问题。这种处理方式不仅保证了 Bean 实例化的正确性,还确保了容器在解决循环依赖时的高性能。
总结
SmartInstantiationAwareBeanPostProcessor 是一个 Spring 容器中的扩展点,它本身并不直接解决循环依赖问题。Spring 容器在解决循环依赖时,主要依赖于 DefaultSingletonBeanRegistry 类中的 getSingleton() 方法,该方法使用了三级缓存来处理循环依赖。
上述过程仅适用于属性注入的情况
SmartInstantiationAwareBeanPostProcessor,它提供了一些扩展点,允许我们在 Spring 容器创建和初始化 Bean 实例的过程中进行干预。例如,我们可以使用它来改变实例化策略、解析依赖关系或者修改属性值等。然而,SmartInstantiationAwareBeanPostProcessor 本身并不直接参与解决循环依赖问题。
总之,Spring 容器通过三级缓存解决属性注入的循环依赖问题。然而,对于构造器注入的循环依赖,我们需要调整代码结构或使用其他技术手段来解决。SmartInstantiationAwareBeanPostProcessor 是一个扩展点,允许我们在 Bean 实例创建和初始化的过程中进行干预,但它本身并不直接解决循环问题
在实际项目中,我们应尽量避免产生循环依赖,以降低代码的复杂度。当循环依赖确实需要解决时,可以尝试以下方法:
使用属性注入而非构造器注入,让 Spring 容器自动处理循环依赖问题。
提取接口,将 A 和 B 的公共功能抽取为接口,然后让 A 和 B 分别依赖这些接口,而不是直接依赖彼此。
使用事件驱动或消息队列,将 A 和 B 之间的交互转移到事件驱动或消息队列中,这样可以避免直接的循环依赖。
调整代码结构,如使用中介者模式、模块化设计等方法,将循环依赖拆分为线性依赖
相关文章:
spring5.1+SmartInstantiationAwareBeanPostProcessor 解决循环依赖
SmartInstantiationAwareBeanPostProcessor 解决循环依赖的过程, 例如上面的 A依赖B, B依赖A SmartInstantiationAwareBeanPostProcessor 是 Spring 中的一个接口,它扩展了 InstantiationAwareBeanPostProcessor 接口并提供了对 Bean 的实例化和属性填充的更高级的…...
apply、call与bind
共同点: 都是函数对象的一个方法,作用是改变函数执行时的上下文,即改变函数体内部this的指向 var name "lucy"; var obj {name: "martin",say: function () {console.log(this.name);} }; obj.say(); // martin&…...
《Effective Objective-C 2.0 》 阅读笔记 item3
第3条:多用字面量语法,少用与之等价的方法 1. 字面数值 使用字面量能令代码更为简洁: NSNumber *someNumber 1; *** 字面量语法的好处! *** 令代码更为简洁。能够以NSNumber实例表示的所有数据类型(int、float、d…...
SSL/TLS 证书管理
SSL 证书发现 随着组织的 IT 基础架构的扩展,他们为每台计算机获取证书以保护其资源和域。此外,开发人员通常会创建许多自签名证书,以便在产品的开发阶段保护内部网络。组织通常最终会拥有数千个证书。自动发现证书提供了对证书基础结构的完…...
supersqli(SQL注入流程及常用SQL语句)
目录 一、SQL注入知识学习 1、判断注入类型 (1)数字型注入判断 (2)字符型注入判断 2、猜解sql查询语句中的字段数(order by 的使用) 3、判断显示位爆数据库的名字 4、注释(--的使用&#…...
【数据结构】用Java实现一棵二叉树
目录 前言 1. 创建MyBinaryTree类 2. 从前序与中序遍历序列构造二叉树 3. 从中序与后序遍历序列构造二叉树 4. 用层序遍历验证二叉树是否构建成功 5. 整体代码(构建二叉树、二叉树的基本功能和测试代码) 6. 测试结果 前言 前面两篇文章已经给出了…...
【面试】面试官问的几率较大的网络安全面试题
文章目录防范常见的 Web 攻击1、什么是SQL注入攻击2、什么是XSS攻击3、什么是CSRF攻击4、什么是文件上传漏洞5、DDos 攻击重要协议分布图1、arp协议的工作原理ARP协议工作原理:2、什么是RARP?工作原理3、dns是什么?dns的工作原理4、rip协议是…...
[Python] 循环语句
循环语句就是在符合条件的情况下,重复执行一个代码段 1.while循环 while语句可用于在条件为真时反复执行代码块 语法格式 while 条件语句:执行语句 当条件语句为真(True)时,就会执行while循环下的语句 示例 实现1到100 的累加并输出求和结果 …...
计算机网络考试复习——第一章 1.5 1.6
1.5 计算机网络的类别 1.5.1计算机网络的定义: 系统集合,连接起来,协议工作,资源共享 计算机网络主要是由一些通用的、可编程的硬件互连而成的,而这些硬件并非专门用来实现某一特定目的(例如࿰…...
3.29 最小生成树算法
最小生成树概念 参考:什么是最小生成树? Minimum Spanning Tree 何为生成树? 生成树是指一个联通图的极小的连通子图,它包含了图中的所有n个顶点,并只有n-1条边(构成一棵树) 生成树的一些性…...
计算机科班与培训开发编程的区别在哪里?
科班、培训班、科班培训班的模式都培养了很多编程技术人员进入IT行业,有的成为某个技术领域的专家,有的成为领导层,有的一直在默默无闻的敲代码等待35岁的到来。不管那种方式入行,这些类似的情况都存在,并且未来还会一…...
idea设置常用自设置快捷键及坐标
<!--mybatis 依赖--> <dependency> <groupId>org.mybatis</groupId> <artifactId>mybatis</artifactId> <version>3.5.5</version> </dependency…...
Vue 3.0 实例方法
#$watch 参数:{string | Function} source{Function | Object} callback{Object} [options] {boolean} deep{boolean} immediate{string} flush返回:{Function} unwatch用法: 侦听组件实例上的响应式 property 或函数计算结果的变化。回调函数…...
日撸 Java 三百行day1-10
文章目录说明day1 环境搭建1.1 开发环境1.2 package import 和 println1.3 编写HelloWorld.javaday2 基本算术操作2.1 加、减、乘、除、整除、取余.day3 基本if 语句3.1 if条件分支语句3.2 代码day4 闰年的计算4.1 思路整理:何为闰年?4.2 核心代码day5 基…...
Ubuntu Instant-ngp 训练自有数据集
1. 运行环境配置 conda create -n instant-ngp python3.10 conda activate instant-ngp pip install -r requirements.txt -i https://pypi.tuna.tsinghua.edu.cn/simple2. COLMAP稀疏重建生成transform.json colmap 环境配置参考文档; 终端定位在instant-ngp/da…...
k8s集群只一台节点,重启节点后命名空间找不到了
定位 如果您的Kubernetes集群只有一台节点,并且在重启节点之前您创建了一些命名空间和资源,那么在节点重启后,这些命名空间和资源可能会丢失。这是因为在Kubernetes中,资源和命名空间通常是存储在etcd中的。当节点重启时…...
MarkDown示例
这里写自定义目录标题欢迎使用Markdown编辑器新的改变功能快捷键合理的创建标题,有助于目录的生成如何改变文本的样式插入链接与图片如何插入一段漂亮的代码片生成一个适合你的列表创建一个表格设定内容居中、居左、居右SmartyPants创建一个自定义列表如何创建一个注…...
spring cloud 雪崩效应
什么是雪崩效应 雪崩就是塌方。在山坡上的积雪,如果积雪的内聚力小于重力或其他力量,则积雪便向下滑动,从而逐渐引起积雪的崩塌。 在微服务架构中,服务之间通常存在级联调用。比如,服务A调用服务B,而服…...
Python 自动化指南(繁琐工作自动化)第二版:三、函数
原文:https://automatetheboringstuff.com/2e/chapter3/ 您已经熟悉了前几章中的print()、input()和len()函数。Python 提供了几个这样的内置函数,但是您也可以编写自己的函数。函数就像一个程序中的一个小程序。 为了更好地理解函数是如何工作的&#…...
c++多线程 1
https://www.runoob.com/cplusplus/cpp-multithreading.html 两种类型的多任务处理:基于进程和基于线程。 基于进程的多任务处理是程序的并发执行。 基于线程的多任务处理是同一程序的片段的并发执行。 线程 c11以后有了 标准库 1 函数 2 类成员函数 3 lambda函…...
Python MCP服务部署成本飙升?5个被90%团队忽略的隐性开销及实时监控方案
第一章:Python MCP服务部署成本飙升的真相与警示Python MCP(Model Control Plane)服务在微服务架构中承担模型注册、版本调度、A/B测试路由等关键职责。近期大量团队反馈其云上部署成本在两周内激增300%以上,远超业务增长曲线。深…...
Prometheus动态服务发现实战:从文件到K8S的三种配置方法对比
Prometheus动态服务发现实战:文件、Consul与Kubernetes的深度对比 在云原生监控体系中,服务发现机制如同神经系统般实时感知基础设施变化。当面对混合架构时,如何在文件、Consul和Kubernetes三种主流方案中做出技术选型?本文将带…...
Qwen3-ASR-1.7B与Python爬虫结合实战:音频数据采集与智能分析流水线
Qwen3-ASR-1.7B与Python爬虫结合实战:音频数据采集与智能分析流水线 1. 为什么需要这套音频分析流水线 最近在帮一家做社交媒体舆情监控的团队搭建分析系统时,他们提出了一个很实际的问题:视频平台里大量用户评论是以语音形式存在的&#x…...
新手必看:Qwen2.5-VL-7B图文对话模型部署与使用全攻略
新手必看:Qwen2.5-VL-7B图文对话模型部署与使用全攻略 1. 环境准备与快速部署 1.1 镜像简介 Qwen2.5-VL-7B-Instruct-GPTQ是基于Qwen2.5-VL-7B-Instruct模型的GPTQ量化版本,专门用于图文对话任务。这个镜像已经预装了vllm推理框架和chainlit前端界面&…...
Legacy iOS Kit:让旧款iOS设备重获新生的全方位解决方案
Legacy iOS Kit:让旧款iOS设备重获新生的全方位解决方案 【免费下载链接】Legacy-iOS-Kit An all-in-one tool to downgrade/restore, save SHSH blobs, and jailbreak legacy iOS devices 项目地址: https://gitcode.com/gh_mirrors/le/Legacy-iOS-Kit 旧设…...
别再让串口指示灯‘瞎闪’了!手把手教你用LM358运放做个‘聪明’的LED驱动电路
别再让串口指示灯‘瞎闪’了!手把手教你用LM358运放做个‘聪明’的LED驱动电路 调试串口通信时,最让人头疼的莫过于那些"瞎闪"的指示灯——波特率一高,LED就像得了癫痫,微弱的光斑根本分不清是发送还是接收。我曾在一个…...
Clawdbot汉化版实测:企业微信接入AI客服,响应速度提升92%
Clawdbot汉化版实测:企业微信接入AI客服,响应速度提升92% 1. 企业客服场景的痛点与解决方案 1.1 传统客服面临的挑战 在电商和客户服务领域,企业微信已成为重要的客户沟通渠道。然而传统客服模式存在三个核心问题: 响应延迟&a…...
OpenClaw本地知识图谱:GLM-4.7-Flash构建个人关系网络
OpenClaw本地知识图谱:GLM-4.7-Flash构建个人关系网络 1. 为什么需要个人知识图谱 去年整理项目资料时,我发现自己收藏的200多篇技术文章和50多个开源项目早已形成"信息孤岛"。当需要跨领域参考时,只能靠模糊记忆在文件夹里大海捞…...
开源大模型部署新范式:像素幻梦Streamlit前端+diffusers后端架构解析
开源大模型部署新范式:像素幻梦Streamlit前端diffusers后端架构解析 1. 项目概览 像素幻梦(Pixel Dream Workshop)是一款基于FLUX.1-dev扩散模型的像素艺术生成工具,它重新定义了AI艺术创作的用户体验。与传统AI绘图工具不同,它采用了独特的…...
面向生产的Chatgpt5.4:系统集成、架构模式与成本优化深度拆解
对于计划将顶级AI能力深度集成至自身产品与工作流的团队而言,理解Gemini 3.1 Pro的系统级特性、集成模式与全生命周期成本至关重要。国内开发者可通过RskAi(www.rsk.cn)等聚合平台,以零成本、国内直访的方式完成前期技术验证与原型…...
