spring循环依赖解决

问题描述

spring循环依赖是对于ioc容器。类A、B、C,类A依赖了B,类A依赖了C,类B依赖了A,类C依赖了A。假如现在类A需要放到ioc,属性赋值的时候会去找B这个bean,但是B不存在,于是去创建B这个bean,但是实例化beanB之后再属性赋值的时候需要注入A这个bean。这样就造成了循环。

解决办法

spring通过三级缓存解决循环依赖问题,首次注入beanA的时候会在类A实例化之后,spring会创建一个ObjectFactory用来后续获取beanA的早期引用,并将这个ObjectFactory放到三级缓存中。接着注入beanB,初始化类B之后属性赋值,需要注入beanA,这是spring会去三级缓存中获取A的ObjectFactory调用getObject()获取A的早期引用,如果A需要被代理(如@Transactional),会在此时去创建A的代理对象,放到二级缓存中,然后删除三级缓存的A的工厂对象。此时returnA这时循环有了出口,就解决了循环依赖。

补充

时序图

  • 实例化->new A(这里把创建A的ObjectFactory放到三级缓存)
  • 属性赋值(循环依赖的时候这里去创建AOP代理)
  • 初始化(正常这里创建aop代理)

三级缓存是为了支持aop代理的按需创建。二级缓存的话就是直接把早期对象放到二级缓存,实例化A之后马上把他放到二级缓存。如果直接把早期对象放到二级缓存,(实例化之后)就无法灵活决定是否创建代理(因为AOP代理是在postProcessAfterInitialization(上图初始化中)中创建的)。可能导致重复创建代理或代理失效。
而如果是三级缓存的话

spring创建一个bean的阶段

1.实例化(instantiation)      ->new A()
2.属性注入(Populate Properties->setB(),setC()
3.初始化(Initialization->调用init-method,BeanPostProcessorpostProcessBeforeInitialization//是BeanPostProcessor的方法初始化方法(@PostConstruct,init-method)postProcessAfterInitialization ->AOP代理就在这里创建!//是BeanPostProcessor的方法
4.放入一级缓存(singletonObject)

Spring 提供了 InstantiationAwareBeanPostProcessor.getEarlyBeanReference() 方法,允许 AOP 模块在早期引用阶段就决定是否创建代理。这个方法会在 ObjectFactory.getObject() 被调用时触发,是提前创建代理的关键入口

代码细节

三级缓存:singletonFactories如下

Map<String, ObjectFactory<?>> singletonFactories

其中键是类名首字母小写。

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

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

相关文章

最新安卓原生对接苹果cms App后端+app(最新优化版)

内容目录一、详细介绍二、效果展示1.部分代码2.效果图展示三、学习资料下载一、详细介绍 一定要按照教程教的来搭建&#xff01; App演示图片 二、效果展示 1.部分代码 代码如下&#xff08;示例&#xff09;&#xff1a; public static function apkinfo(){return self::…

嵌入式硬件中运放的基本控制原理

上次课的最后是给大家总结一些基础电子知识的,我们接着往下讲。我们知道了运放的虚短虚断的概念理论上来说 可以进行计算了是吧。 这个图实际上是一个正输入信号的同相放大电路,我们看下如何计算,第一先看虚断。运放的输入脚内部对地是阻抗十分大是吧,那么这个正输入脚上的…

聚集索引与非聚集索引的区别

聚集索引&#xff08;Clustered Index&#xff09;和非聚集索引&#xff08;Non-Clustered Index&#xff09;是索引设计的核心概念&#xff0c;二者的本质区别体现在 与数据物理存储的关联方式 上&#xff0c;这种区别直接决定了它们的性能特性和适用场景。我们平时说的 聚簇索…

《零基础入门AI:传统机器学习进阶(从拟合概念到K-Means算法)》

一、欠拟合与过拟合欠拟合(Underfitting) 欠拟合是指模型在训练数据上表现不佳&#xff0c;同时在新的未见过的数据上也表现不佳。这通常发生在模型过于简单&#xff0c;无法捕捉数据中的复杂模式时。欠拟合模型的表现特征如下&#xff1a; 训练误差较高。测试误差同样较高。模…

Datawhale AI夏令营 第三期 task2 稍微改进

在打造基于大语言模型&#xff08;LLM&#xff09;文档检索的问答系统中&#xff0c;财经研报类文档是最具挑战的场景之一。它包含图文混排、精细定位需求&#xff08;页码、文件名&#xff09;、问题措辞高度多样化等一系列复杂性。 下面的内容是大模型辅助整理的&#xff1a;…

LeetCood算法题~水果成篮

水果成篮 你正在探访一家农场&#xff0c;农场从左到右种植了一排果树。这些树用一个整数数组 fruits 表示&#xff0c;其中 fruits[i] 是第 i 棵树上的水果 种类 。你想要尽可能多地收集水果。然而&#xff0c;农场的主人设定了一些严格的规矩&#xff0c;你必须按照要求采摘水…

【Lua】题目小练8

-- 题目 1&#xff1a;定义一个类 Person-- 属性&#xff1a;name、age&#xff0c;其中 age 默认是 0&#xff0c;不能小于 0。-- 方法&#xff1a;introduce()&#xff0c;输出 "My name is <name>, I am <age> years old."-- 要求使用封装思想&#x…

SAP PP CK466

原因 作业价格没有维护 解决方案 KP26

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

【Python系列Bug修复PyCharm控制台pip install报错】如何解决pip安装报错ModuleNotFoundError: No module named ‘keras’问题 摘要 在使用 PyCharm 进行深度学习项目开发时&#xff0c;常常需要通过 pip install keras 来安装 Keras 库。但有时即便命令执行成功&#xff0c…

人工智能领域、图欧科技、IMYAI智能助手2024年全年历史更新大事件汇总

2024年 2024年12月29日 【通知】 1、主站导出文档功能优化升级&#xff0c;新增支持了纯文本WORD导出功能&#xff0c;支持使用WPS软件打开 注&#xff1a;原来的富文本WORD不支持使用WPS打开&#xff0c;只支持系统自带的WORD软件打开&#xff0c;比如Microsoft Office Word 2…

UWB实操:使用UCI CMD测距;UCI CMD是一串数字,创建测距session,配置测距session,开始测距session。

使用UCI CMD测距; UCI CMD是一串数字,创建测距session,配置测距session,开始测距session。根据 FiRa_UCI_Technical_Specification,我们可以分析并组织测距cmd 例如: Fira2.0 1v1 发起 DSTWR 创建测距session:210000052222222200 配置测距session: 2103001F222…

从AUTOSAR角度理解CAN以及CANFD

一、AUTOSAR对CAN和CAN FD的基础定位 CAN&#xff1a;基于传统CAN 2.0B协议&#xff0c;是AUTOSAR早期版本&#xff08;如4.0.3及之前&#xff09;的核心车载通信协议&#xff0c;支持最大8字节 payload&#xff0c;仲裁段波特率通常≤1Mbps&#xff0c;适用于低带宽、高实时性…

第27章:服务部署与容器化

1. 课程引言 在前面的章节中&#xff0c;我们已经完成了电商项目核心服务的开发。然而&#xff0c;开发完成只是项目生命周期的一部分&#xff0c;如何将这些服务高效、可靠地部署到生产环境&#xff0c;是决定项目成败的关键一步。本章将聚焦于服务的部署&#xff0c;重点介绍…

力扣148:排序链表

力扣148:排序链表题目思路代码题目 给你链表的头结点 head &#xff0c;请将其按 升序 排列并返回 排序后的链表 。 思路 当我们第一眼看见这道题时心中其实是有思路的&#xff0c;我们不想这是个链表就当它是一个整型数组。那么自然而然就会想到各种各样的排序方法&#xf…

基于k8s环境下的pulsar常用命令(下)

#作者&#xff1a;Unstopabler 文章目录permissionSchemapermission pulsar的权限控制是在namespace级别的 kubectl exec pulsar-toolset-0 -n pulsar – bin/pulsar-admin namespaces grant-permission mytenant/mynamespace –actions produce,consume –role admin10 注…

2.4 组件通信

Props 和 Events&#xff08;父子组件通信&#xff09;Props&#xff1a;父组件向子组件传递数据使用 props。子组件通过声明 props 来接收来自父组件的数据。<!-- 父组件 --> <template><ChildComponent :message"parentMessage" /> </templat…

PCL学习之路-基础知识-(一)

文章目录1.西门子S7系列PLC类型划分(1).大型PLC&#xff1a;S7-400(2).中型PLC&#xff1a;S7-300(3).小型PLC&#xff1a;S7-200系列2.西门子S7外形结构(1).总览&#xff1a;PLC的“器官”分工逻辑3.输出电路(1).小型继电器输出形式(2).大功率晶体管/场效应管输出形式(3).双向…

leetcode654:最大二叉树(递归与单调栈双解法)

文章目录一、 题目描述二、 核心思路&#xff1a;分而治之与递归构造三、代码实现与深度解析四、 关键点与复杂度分析五、拓展解法单调栈解法两种解法对比LeetCode 654. 最大二叉树&#xff0c;【难度&#xff1a;中等&#xff1b;通过率&#xff1a;82.6%】&#xff0c;这道题…

Python 循环语法详解

在编程中&#xff0c;循环是一种非常常见的控制结构。很多时候&#xff0c;我们需要重复做一些事情&#xff0c;比如遍历列表、处理数据、尝试直到成功等。这时候&#xff0c;就离不开循环了。Python 提供了两种主要的循环结构&#xff1a;for 循环 和 while 循环。本篇文章会从…

一个小巧神奇的 USB数据线检测仪

一个小巧的数据线检测仪&#xff0c;检测各种USB数据线是否损坏、通断&#xff0c;TYPE_C、MICRO_B、苹果线、烧录线、网线都可检测。嵌入式开发者的称手工具。 这个是我个人制作的&#xff0c;SMT和连接器比较贵&#xff0c;特别是24PIN的C口连接器&#xff0c;我挂在黄色小鱼…