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

spring解决循环依赖的三级缓存

一、Spring在创建Bean的过程中分三步

  1. 实例化,对应方法:AbstractAutowireCapableBeanFactory中的createBeanInstance方法,简单理解就是new了一个对象。
  2. 属性注入,对应方法:AbstractAutowireCapableBeanFactory的populateBean方法,为实例化中new出来的对象填充属性和注入依赖。
  3. 初始化,对应方法:AbstractAutowireCapableBeanFactory的initializeBean,执行aware接口中的方法,初始化方法,完成AOP代理。

二、三级缓存:

private final Map<String, Object> singletonObjects = new ConcurrentHashMap<>(256);
private final Map<String, Object> earlySingletonObjects = new HashMap<>(16);
private final Map<String, ObjectFactory<?>> singletonFactories = new HashMap<>(16);

singletonObjects第一级缓存,存放可用的完全初始化,成品的单例Bean。

earlySingletonObjects第二级缓存,存放半成品的Bean,半成品的Bean是已创建对象,但是未注入属性和初始化。用以解决循环依赖。

singletonFactories第三级缓存,存的是Bean工厂对象,用来生成半成品的Bean并放入到二级缓存中。用以解决循环依赖。如果Bean存在AOP的话,返回的是AOP的代理对象

三级缓存的 key 是 beanName,value 是一个 lambda 表达式,这个 lambda 表达式的作用就是进行提前 AOP。

三、三个 map 的配合过程:

1、首先,获取单例 Bean 的时候会通过 BeanName 先去 singletonObjects(一级缓存) 查找完整的 Bean,如果找到则直接返回,否则进行步骤 2。

2、看对应的 Bean 是否在创建中,如果不在直接返回找不到,如果是,则会去 earlySingletonObjects (二级缓存)查找 Bean,如果找到则返回,否则进行步骤 3。

3、去 singletonFactories (三级缓存)通过 BeanName 查找到对应的工厂,如果存着工厂则通过工厂创建 Bean ,并且放置到 earlySingletonObjects 中。

4、如果三个缓存都没找到,则返回 null。

为了解决二级缓存中 AOP 生成新对象的问题,Spring 中的解决方案就是提前 AOP。

四、Spring 为什么不用二级缓存来解决循环依赖问题?

Spring 原本的设计是,bean 的创建过程分三个阶段:
1 创建实例 createBeanInstance – 创建出 bean 的原始对象
2 填充依赖 populateBean – 利用反射,使用 BeanWrapper 来设置属性值
3 initializeBean – 执行 bean 创建后的处理,包括 AOP 对象的产生
在没有循环依赖的场景下:第 1,2 步都是 bean 的原始对象,第 3 步 initializeBean 时,才会生成 AOP 代理对象。

循环依赖属于一个特殊的场景,如果在第 3 步 initializeBean 时才去生成 AOP 代理 bean 的话,那么在第 2 步 populateBean 注入循环依赖 bean 时就拿不到 AOP 代理 bean 进行注入。
所以,循环依赖打破了 AOP 代理 bean 生成的时机,需要在 populateBean 之前就生成 AOP 代理 bean。
而且,生成 AOP 代理需要执行 BeanPostProcessor,而 Spring 原本的设计是在第 3 步 initializeBean 时才去调用 BeanPostProcessor 的。
并不是每个 bean 都需要进行这样的处理,所以, Spring 没有直接在 createBeanInstance 之后直接生成 bean 的早期引用,而是将 bean 的原始对象包装成了一个 ObjectFactory 放到了三级缓存singletonFactories。
当需要用到 bean 的早期引用的时候,才通过三级缓存singletonFactories 来进行获取。

如果只使用二级缓存来解决循环依赖的话,那么每个 bean 的创建流程中都需要插入一个流程——创建 bean 的早期引用放入二级缓存。

实际中绝大部分的情况下都不涉及到循环依赖,而且 createBeanInstance --> populateBean --> initializeBean 这个流程也更加符合常理。

所以,猜想Spring 不用二级缓存来解决循环依赖问题,是为了保证处理时清晰明了,bean 的创建就是三个阶段: createBeanInstance --> populateBean --> initializeBean
只有碰到 AOP 代理 bean 被循环依赖时的场景,才去特殊处理,提前生成 AOP 代理 bean。

理论上来说,使用二级缓存是可以解决 AOP 代理 bean 的循环依赖的。只是 Spring 没有选择这样去实现,Spring 选择了三级缓存来实现,让 bean 的创建流程更加符合常理,更加清晰明了。

五、多例不能循环依赖

多例的情况下,每次getBean都会创建一个新的对象,那么应该引用哪一个对象呢?这本身就矛盾。多实例Bean是每次创建都会调用doGetBean方法,根本没有使用一二三级缓存,不能解决循环依赖。因而spring中对于多例之间相互引用是会提示错误的。

相关文章:

spring解决循环依赖的三级缓存

一、Spring在创建Bean的过程中分三步 实例化&#xff0c;对应方法&#xff1a;AbstractAutowireCapableBeanFactory中的createBeanInstance方法&#xff0c;简单理解就是new了一个对象。属性注入&#xff0c;对应方法&#xff1a;AbstractAutowireCapableBeanFactory的populat…...

C++ - 标准库(STL)

目录 一、简介 二、什么时候使用STL 2.1、 vector 和 deque 的使用场景 2.2、 vector 和 deque 的比较 2.3、 list的使用场景 一、简介 C标准库是C编程语言的标准程式库&#xff0c;它提供了一个通用的容器类、算法和函数模板库。 其中包括了多种容器类型&#xff0c;例…...

Java使用 Scanner连续输入int, String 异常错误输出原因分析

目录 一、Scanner常用语法 1、sc.nextInt()介绍 2、sc.next()介绍 3、sc.nextLine()介绍 4、sc.hasNext()介绍 二、报错案例 1、使用next()来接收带有空格的字符串会输出异常 2、先输入数字再输入字符串的输出异常 一、Scanner常用语法 Scanner sc new Scanner(System.…...

pt13网络编程

网络编程 OSI 7层模型 建立了统一的通信标准 降低开发难度&#xff0c;每层功能明确&#xff0c;各司其职 七层模型实际规定了每一层的任务&#xff0c;该完成什么事情 TCP/IP模型 七层模型过于理想&#xff0c;结构细节太复杂在工程中应用实践难度大实际工作中以TCP/IP模型…...

华为云 绑定/更换证书

操作场景 为了支持HTTPS数据传输加密认证&#xff0c;在创建HTTPS协议监听的时候需绑定证书&#xff0c;您可以参考本章节绑定证书。如果弹性负载均衡实例使用的证书过期或者其它原因需要更换&#xff0c;您可以参考本章节更换证书。如果还有其他的服务也使用了待更换的证书&a…...

重大问题,Windows11出现重大BUG

重大问题&#xff0c;Windows11出现重大BUG 这种Windows11操作系统出现BUG已经可以说是非常常见的&#xff0c;但是&#xff0c;今天我将代表所有微软用户&#xff0c;解决一个关于UI设计非常不舒服的功能 关闭多平面覆盖 事情叙述问题 微软社区解决方案自己发现的解决方案解决…...

傅里叶变换解析

p.s.本文无论是cos还是sin&#xff0c;都统一用“正弦波”(Sine Wave)一词来代表简谐波。 一、什么是频域 从我们出生&#xff0c;我们看到的世界都以时间贯穿&#xff0c;股票的走势、人的身高、汽车的轨迹都会随着时间发生改变。这种以时间作为参照来观察动态世界的方法我们称…...

你的登录接口真的安全吗?

1.前言 大家学写程序时&#xff0c;第一行代码都是hello world。但是当你开始学习WEB后台技术时&#xff0c;很多人的第一个功能就是写的登录 &#xff08;小声&#xff1a;别人我不知道&#xff0c;反正我是&#xff09;。但是我在和很多工作经验较短的同学面试或沟通的时候&…...

ChatGPT情商很高,但并不适合当搜索引擎

微软和谷歌正急于使用大型语言模型技术来强化搜索引擎。但有充分的理由认为&#xff0c;相比于提供事实性信息&#xff0c;这项技术更适合作为人们情感上的伴侣。 美媒评论称&#xff0c;目前基于大型语言模型的人工智能工具&#xff0c;例如ChatGPT&#xff0c;更擅长共情而不…...

Mac 地址与 IP 地址有什么区别?

Mac 地址和 IP 地址是两个不同的概念&#xff0c;它们分别代表了计算机网络中的不同层次和地址。Mac 地址是物理地址&#xff0c;是在计算机硬件中存储的地址&#xff0c;通常是以特定的六进制格式表示。每个设备都有一个唯一的 MAC 地址&#xff0c;它可以用来在计算机之间进行…...

bootloaders

什么是BootLoader? 一般来说&#xff0c;bootloader是一种软件/固件&#xff0c;它在SoC上电后立即运行。bootloader的主要职责是启动软件的后续部分&#xff0c;例如操作系统、baremetal应用程序或在某些情况下另一个bootloader。当涉及到嵌入式时&#xff0c;bootloader通常…...

PC或服务器装双系统

1. 准备工作 1.1U盘启动盘的制作 ①准备一个 4G 以上的 U 盘&#xff0c;备份好U盘资料&#xff0c;后面会对 U 盘进行格式化。 ②去CentOS官网下载你想要安装的 ISO 格式镜像文件&#xff0c;现在通常是CentOS6、7或者8。如果你英文不太好&#xff0c;可以选择使用edge浏览…...

嵌入式代码查看分析利器---Understand

平时在开发嵌入式程序的时候大多数使用的都是keil软件&#xff0c;一般小的工程使用keil没感觉到有什么问题&#xff0c;但是当工程比较大的时候&#xff0c;比如移植了FreeRTOS系统或者LWIP网络系统时&#xff0c;代码全部编译一次就要花费很长世间&#xff0c;特别是开启了点…...

人群计数经典方法Density Map Estimation,密度图估计

&#xff08;3&#xff09;Density Map Estimation&#xff08;主流&#xff09; 这是crowd counting的主流方法 传统方法不好在哪里&#xff1f;object detection-based method和regression-based method无法从图像中提取更抽象的有助于完成人群计数任务的语义特征 概况&…...

【华为】Smart-Link基础知识

Smark-Link技术 Smark-Link(灵活链路or备份链路&#xff0c;华为/华三 私有用) Smark-Link定义 Smark-Link&#xff0c;又叫备份链路。一个Smark Link由两个接口组组成&#xff0c;其中一个接口作为另一个的备份。Smark-Link常用于双上行组网&#xff0c;提供可靠高效的备份与…...

分享24个强大的HTML属性 —— 建议每位前端工程师都应该掌握

前期回顾 是不是在为 API 烦恼 &#xff1f;好用免费的api接口大全呼之欲出_0.活在风浪里的博客-CSDN博客APi、常用框架、UI、文档—— 整理合并https://blog.csdn.net/m0_57904695/article/details/130459417?spm1001.2014.3001.5501 &#x1f44d; 本文专栏&#xff1a;…...

NIO基础 - 网络编程

non-blocking io 非阻塞 IO 1. 三大组件 1.1 Channel & Buffer channel 有一点类似于 stream&#xff0c;它就是读写数据的双向通道&#xff0c;可以从 channel 将数据读入 buffer&#xff0c;也可以将 buffer 的数据写入 channel&#xff0c;而之前的 stream 要么是输入…...

06.toRef 和 toRefs

学习要点&#xff1a; 1.toRef 和 toRefs 本节课我们来要了解一下 Vue3.x 中的 ref 两个周边 API 的用法&#xff1b; 一&#xff0e;toRef 和 toRefs 1. toRef 可以将源响应式对象上的 property 创建一个 ref 对象&#xff1b; const obj reactive({ name : Mr.Lee, age : 10…...

RabbitMq、Kafka、RocketMq整理

MQ的主要作用:异步提高性能、解耦提高扩展性、削峰。 一、常见中间件对比 Kafka、RocketMq和RabbitMq最大的区别就是:前两个是分布式存储。 1.1、ActiveMq 优点:1)完全支持jms规范的消息中间件 ,2)提供丰富的api, 3)多种集群构建模式。 缺点:)在高并发的场景下,性能可…...

Python多元线性回归预测模型实验完整版

多元线性回归预测模型 实验目的 通过多元线性回归预测模型&#xff0c;掌握预测模型的建立和应用方法&#xff0c;了解线性回归模型的基本原理 实验内容 多元线性回归预测模型 实验步骤和过程 (1)第一步&#xff1a;学习多元线性回归预测模型相关知识。 一元线性回归模型…...

零门槛NAS搭建:WinNAS如何让普通电脑秒变私有云?

一、核心优势&#xff1a;专为Windows用户设计的极简NAS WinNAS由深圳耘想存储科技开发&#xff0c;是一款收费低廉但功能全面的Windows NAS工具&#xff0c;主打“无学习成本部署” 。与其他NAS软件相比&#xff0c;其优势在于&#xff1a; 无需硬件改造&#xff1a;将任意W…...

调用支付宝接口响应40004 SYSTEM_ERROR问题排查

在对接支付宝API的时候&#xff0c;遇到了一些问题&#xff0c;记录一下排查过程。 Body:{"datadigital_fincloud_generalsaas_face_certify_initialize_response":{"msg":"Business Failed","code":"40004","sub_msg…...

Spark 之 入门讲解详细版(1)

1、简介 1.1 Spark简介 Spark是加州大学伯克利分校AMP实验室&#xff08;Algorithms, Machines, and People Lab&#xff09;开发通用内存并行计算框架。Spark在2013年6月进入Apache成为孵化项目&#xff0c;8个月后成为Apache顶级项目&#xff0c;速度之快足见过人之处&…...

DeepSeek 赋能智慧能源:微电网优化调度的智能革新路径

目录 一、智慧能源微电网优化调度概述1.1 智慧能源微电网概念1.2 优化调度的重要性1.3 目前面临的挑战 二、DeepSeek 技术探秘2.1 DeepSeek 技术原理2.2 DeepSeek 独特优势2.3 DeepSeek 在 AI 领域地位 三、DeepSeek 在微电网优化调度中的应用剖析3.1 数据处理与分析3.2 预测与…...

rknn优化教程(二)

文章目录 1. 前述2. 三方库的封装2.1 xrepo中的库2.2 xrepo之外的库2.2.1 opencv2.2.2 rknnrt2.2.3 spdlog 3. rknn_engine库 1. 前述 OK&#xff0c;开始写第二篇的内容了。这篇博客主要能写一下&#xff1a; 如何给一些三方库按照xmake方式进行封装&#xff0c;供调用如何按…...

2025年能源电力系统与流体力学国际会议 (EPSFD 2025)

2025年能源电力系统与流体力学国际会议&#xff08;EPSFD 2025&#xff09;将于本年度在美丽的杭州盛大召开。作为全球能源、电力系统以及流体力学领域的顶级盛会&#xff0c;EPSFD 2025旨在为来自世界各地的科学家、工程师和研究人员提供一个展示最新研究成果、分享实践经验及…...

visual studio 2022更改主题为深色

visual studio 2022更改主题为深色 点击visual studio 上方的 工具-> 选项 在选项窗口中&#xff0c;选择 环境 -> 常规 &#xff0c;将其中的颜色主题改成深色 点击确定&#xff0c;更改完成...

【CSS position 属性】static、relative、fixed、absolute 、sticky详细介绍,多层嵌套定位示例

文章目录 ★ position 的五种类型及基本用法 ★ 一、position 属性概述 二、position 的五种类型详解(初学者版) 1. static(默认值) 2. relative(相对定位) 3. absolute(绝对定位) 4. fixed(固定定位) 5. sticky(粘性定位) 三、定位元素的层级关系(z-i…...

在四层代理中还原真实客户端ngx_stream_realip_module

一、模块原理与价值 PROXY Protocol 回溯 第三方负载均衡&#xff08;如 HAProxy、AWS NLB、阿里 SLB&#xff09;发起上游连接时&#xff0c;将真实客户端 IP/Port 写入 PROXY Protocol v1/v2 头。Stream 层接收到头部后&#xff0c;ngx_stream_realip_module 从中提取原始信息…...

Mac软件卸载指南,简单易懂!

刚和Adobe分手&#xff0c;它却总在Library里给你写"回忆录"&#xff1f;卸载的Final Cut Pro像电子幽灵般阴魂不散&#xff1f;总是会有残留文件&#xff0c;别慌&#xff01;这份Mac软件卸载指南&#xff0c;将用最硬核的方式教你"数字分手术"&#xff0…...