当前位置: 首页 > news >正文

spring5.1+SmartInstantiationAwareBeanPostProcessor 解决循环依赖

SmartInstantiationAwareBeanPostProcessor 解决循环依赖的过程, 例如上面的 A依赖B, B依赖A

SmartInstantiationAwareBeanPostProcessor 是 Spring 中的一个接口,它扩展了 InstantiationAwareBeanPostProcessor 接口并提供了对 Bean 的实例化和属性填充的更高级的控制。在 Spring Boot 项目中,SmartInstantiationAwareBeanPostProcessor 通过三级缓存机制解决了循环依赖的问题。以 A 依赖 B,B 依赖 A 为例,我们来了解下这个过程:

  1. 当容器开始实例化 A 时,首先会调用 SmartInstantiationAwareBeanPostProcessor#predictBeanType 方法来预测 Bean 的类型。如果可以预测到类型,Spring 会优先使用这个类型来实例化对象。

  2. 接下来会调用 SmartInstantiationAwareBeanPostProcessor#getEarlyBeanReference 方法获取 A 的提前暴露的引用。这个引用通常是一个代理对象,它可以处理 A 对 B 的依赖。

  3. 将 A 的提前暴露引用放入三级缓存。三级缓存分别是 singletonObjects、earlySingletonObjects 和 singletonFactories。其中,singletonObjects 用于存放完全初始化好的单例 Bean,earlySingletonObjects 用于存放提前暴露的 Bean 引用,singletonFactories用于存放原始 Bean 的工厂对象。在这个例子中,A 的提前暴露引用会被放入 earlySingletonObjects 缓存。

  4. 接下来,容器开始实例化 B。同样地,会调用 SmartInstantiationAwareBeanPostProcessor#predictBeanType 和 SmartInstantiationAwareBeanPostProcessor#getEarlyBeanReference 方法获取 B 的提前暴露引用,并将其放入 earlySingletonObjects 缓存。

  5. 当 B 的实例化完成后,开始填充属性。这时会发现 B 依赖 A,于是会从三级缓存中获取 A 的引用。由于 A 正在创建过程中,所以从 earlySingletonObjects 缓存中获取到了 A 的提前暴露引用。将 A 的引用设置到 B 的属性上,完成 B 的属性填充。

  6. B 的实例化和属性填充完成后,将 B 从 earlySingletonObjects 移动到 singletonObjects 缓存中。

  7. 接下来,开始填充 A 的属性。由于 A 依赖 B,会从三级缓存中获取 B 的引用。此时,B 已经完全初始化完成,所以从 singletonObjects 缓存中获取到了 B 的引用。将 B 的引用设置到 A 的属性上,完成 A 的属性填充。

  8. A 的实例化和属性填充完成后,将 A 从 earlySingletonObjects 移动到 singletonObjects 缓存中。至此,A 和 B 的循环依赖解决了。

  9. 容器会继续调用各个 BeanPostProcessor 的 postProcessAfterInitialization 方法,对 A 和 B 进行后置处理。这些后置处理可能包括代理对象的创建等操作。

  10. 最后,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计算机网络的定义: 系统集合,连接起来,协议工作,资源共享 计算机网络主要是由一些通用的、可编程的硬件互连而成的,而这些硬件并非专门用来实现某一特定目的(例如&#xff0…...

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 参数&#xff1a;{string | Function} source{Function | Object} callback{Object} [options] {boolean} deep{boolean} immediate{string} flush返回&#xff1a;{Function} unwatch用法&#xff1a; 侦听组件实例上的响应式 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 思路整理&#xff1a;何为闰年&#xff1f;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 环境配置参考文档&#xff1b; 终端定位在instant-ngp/da…...

k8s集群只一台节点,重启节点后命名空间找不到了

定位 如果您的Kubernetes集群只有一台节点&#xff0c;并且在重启节点之前您创建了一些命名空间和资源&#xff0c;那么在节点重启后&#xff0c;这些命名空间和资源可能会丢失。这是因为在Kubernetes中&#xff0c;资源和命名空间通常是存储在etcd中的。当节点重启时&#xf…...

MarkDown示例

这里写自定义目录标题欢迎使用Markdown编辑器新的改变功能快捷键合理的创建标题&#xff0c;有助于目录的生成如何改变文本的样式插入链接与图片如何插入一段漂亮的代码片生成一个适合你的列表创建一个表格设定内容居中、居左、居右SmartyPants创建一个自定义列表如何创建一个注…...

spring cloud 雪崩效应

什么是雪崩效应 雪崩就是塌方。在山坡上的积雪&#xff0c;如果积雪的内聚力小于重力或其他力量&#xff0c;则积雪便向下滑动&#xff0c;从而逐渐引起积雪的崩塌。 在微服务架构中&#xff0c;服务之间通常存在级联调用。比如&#xff0c;服务A调用服务B&#xff0c;而服…...

Python 自动化指南(繁琐工作自动化)第二版:三、函数

原文&#xff1a;https://automatetheboringstuff.com/2e/chapter3/ 您已经熟悉了前几章中的print()、input()和len()函数。Python 提供了几个这样的内置函数&#xff0c;但是您也可以编写自己的函数。函数就像一个程序中的一个小程序。 为了更好地理解函数是如何工作的&#…...

c++多线程 1

https://www.runoob.com/cplusplus/cpp-multithreading.html 两种类型的多任务处理&#xff1a;基于进程和基于线程。 基于进程的多任务处理是程序的并发执行。 基于线程的多任务处理是同一程序的片段的并发执行。 线程 c11以后有了 标准库 1 函数 2 类成员函数 3 lambda函…...

IDEA运行Tomcat出现乱码问题解决汇总

最近正值期末周&#xff0c;有很多同学在写期末Java web作业时&#xff0c;运行tomcat出现乱码问题&#xff0c;经过多次解决与研究&#xff0c;我做了如下整理&#xff1a; 原因&#xff1a; IDEA本身编码与tomcat的编码与Windows编码不同导致&#xff0c;Windows 系统控制台…...

盘古信息PCB行业解决方案:以全域场景重构,激活智造新未来

一、破局&#xff1a;PCB行业的时代之问 在数字经济蓬勃发展的浪潮中&#xff0c;PCB&#xff08;印制电路板&#xff09;作为 “电子产品之母”&#xff0c;其重要性愈发凸显。随着 5G、人工智能等新兴技术的加速渗透&#xff0c;PCB行业面临着前所未有的挑战与机遇。产品迭代…...

Debian系统简介

目录 Debian系统介绍 Debian版本介绍 Debian软件源介绍 软件包管理工具dpkg dpkg核心指令详解 安装软件包 卸载软件包 查询软件包状态 验证软件包完整性 手动处理依赖关系 dpkg vs apt Debian系统介绍 Debian 和 Ubuntu 都是基于 Debian内核 的 Linux 发行版&#xff…...

可靠性+灵活性:电力载波技术在楼宇自控中的核心价值

可靠性灵活性&#xff1a;电力载波技术在楼宇自控中的核心价值 在智能楼宇的自动化控制中&#xff0c;电力载波技术&#xff08;PLC&#xff09;凭借其独特的优势&#xff0c;正成为构建高效、稳定、灵活系统的核心解决方案。它利用现有电力线路传输数据&#xff0c;无需额外布…...

生成 Git SSH 证书

&#x1f511; 1. ​​生成 SSH 密钥对​​ 在终端&#xff08;Windows 使用 Git Bash&#xff0c;Mac/Linux 使用 Terminal&#xff09;执行命令&#xff1a; ssh-keygen -t rsa -b 4096 -C "your_emailexample.com" ​​参数说明​​&#xff1a; -t rsa&#x…...

拉力测试cuda pytorch 把 4070显卡拉满

import torch import timedef stress_test_gpu(matrix_size16384, duration300):"""对GPU进行压力测试&#xff0c;通过持续的矩阵乘法来最大化GPU利用率参数:matrix_size: 矩阵维度大小&#xff0c;增大可提高计算复杂度duration: 测试持续时间&#xff08;秒&…...

Android 之 kotlin 语言学习笔记三(Kotlin-Java 互操作)

参考官方文档&#xff1a;https://developer.android.google.cn/kotlin/interop?hlzh-cn 一、Java&#xff08;供 Kotlin 使用&#xff09; 1、不得使用硬关键字 不要使用 Kotlin 的任何硬关键字作为方法的名称 或字段。允许使用 Kotlin 的软关键字、修饰符关键字和特殊标识…...

LINUX 69 FTP 客服管理系统 man 5 /etc/vsftpd/vsftpd.conf

FTP 客服管理系统 实现kefu123登录&#xff0c;不允许匿名访问&#xff0c;kefu只能访问/data/kefu目录&#xff0c;不能查看其他目录 创建账号密码 useradd kefu echo 123|passwd -stdin kefu [rootcode caozx26420]# echo 123|passwd --stdin kefu 更改用户 kefu 的密码…...

R 语言科研绘图第 55 期 --- 网络图-聚类

在发表科研论文的过程中&#xff0c;科研绘图是必不可少的&#xff0c;一张好看的图形会是文章很大的加分项。 为了便于使用&#xff0c;本系列文章介绍的所有绘图都已收录到了 sciRplot 项目中&#xff0c;获取方式&#xff1a; R 语言科研绘图模板 --- sciRplothttps://mp.…...

Python异步编程:深入理解协程的原理与实践指南

&#x1f49d;&#x1f49d;&#x1f49d;欢迎莅临我的博客&#xff0c;很高兴能够在这里和您见面&#xff01;希望您在这里可以感受到一份轻松愉快的氛围&#xff0c;不仅可以获得有趣的内容和知识&#xff0c;也可以畅所欲言、分享您的想法和见解。 持续学习&#xff0c;不断…...