Spring循环依赖解决机制中引入了三级缓存,这是因为仅使用二级缓存无法灵活处理代理Bean的早期暴露需求。以下是为什么需要三级缓存的详细分析:

1. 二级缓存的局限性

二级缓存通常用于存储早期暴露的未完全初始化的Bean实例。但在AOP代理场景下,Bean可能需要在完全初始化之前暴露其代理对象,而代理对象需要通过特定的工厂方法生成。这种动态代理的场景导致了二级缓存无法直接满足需求,因为它无法预知或动态生成代理对象。

假设使用二级缓存:

  • 如果提前将原始Bean放入二级缓存,后续需要使用代理对象时,就会因为二级缓存中存的是原始对象而导致错误。
  • 如果直接放代理对象,则需要在初始化之前生成代理对象,这与Spring的生命周期管理冲突。

2. 三级缓存的灵活性

三级缓存解决了上述问题,它通过存储一个可以动态生成Bean实例的工厂(ObjectFactory),为Spring提供了更大的灵活性:

  • 如果需要原始对象,可以通过工厂获取原始Bean。
  • 如果需要代理对象,可以通过工厂动态创建并返回代理对象。

三级缓存的流程:

  1. 创建Bean实例后,将其对应的工厂放入三级缓存(singletonFactories)。
  2. 在注入依赖时,如果需要该Bean的引用,先从一级缓存查找,若找不到,再从二级缓存查找,仍找不到时,从三级缓存通过工厂获取Bean。
  3. 如果三级缓存的工厂生成了代理对象,则可以将代理对象存入二级缓存供后续使用。
  4. 最终,当Bean完成初始化后,将完整的Bean放入一级缓存,并移除二级和三级缓存。

3. 为什么不能只用二级缓存?

在没有AOP或代理对象需求的情况下,二级缓存可以满足简单的循环依赖问题。然而,在复杂场景(如AOP)下:

  • 直接暴露实例可能导致后续操作无法使用代理对象。
  • 直接暴露代理对象可能导致代理过早生成,与Spring生命周期不符。

    因此,需要三级缓存来支持动态灵活的代理对象生成和原始对象的按需暴露。

4. 三级缓存的实际优势

三级缓存的引入提供了以下优势:

  1. 支持AOP代理的动态生成,解决代理Bean和循环依赖之间的矛盾。
  2. 避免提前暴露不完整的Bean,确保Bean生命周期管理的规范性。
  3. 提供了一个灵活的机制,可以在不同场景下按需生成不同形式的Bean(原始Bean或代理Bean)。

总结:

二级缓存虽然能够解决部分循环依赖问题,但在涉及动态代理和AOP时,它无法满足所有需求。三级缓存通过存储ObjectFactory,提供了动态生成和按需暴露的能力,从而使Spring能够更全面地解决循环依赖问题。

为什么 Spring 循环依赖需要三级缓存,二级不够吗?的更多相关文章

  1. 【Spring系列】- Spring循环依赖

    Spring循环依赖 生命不息,写作不止 继续踏上学习之路,学之分享笔记 总有一天我也能像各位大佬一样 一个有梦有戏的人 @怒放吧德德 分享学习心得,欢迎指正,大家一起学习成长! 目录 Spring循 ...

  2. 帮助你更好的理解Spring循环依赖

    网上关于Spring循环依赖的博客太多了,有很多都分析的很深入,写的很用心,甚至还画了时序图.流程图帮助读者理解,我看了后,感觉自己是懂了,但是闭上眼睛,总觉得还没有完全理解,总觉得还有一两个坎过不去 ...

  3. Spring 循环依赖的三种方式(三级缓存解决Set循环依赖问题)

    本篇文章解决以下问题: [1] . Spring循环依赖指的是什么? [2] . Spring能解决哪种情况的循环依赖?不能解决哪种情况? [3] . Spring能解决的循环依赖原理(三级缓存) 一 ...

  4. Spring 循环依赖

    循环依赖就是循环引用,就是两个或多个Bean相互之间的持有对方,比如CircleA引用CircleB,CircleB引用CircleC,CircleC引用CircleA,则它们最终反映为一个环.此处不 ...

  5. Springboot源码分析之Spring循环依赖揭秘

    摘要: 若你是一个有经验的程序员,那你在开发中必然碰到过这种现象:事务不生效.或许刚说到这,有的小伙伴就会大惊失色了.Spring不是解决了循环依赖问题吗,它是怎么又会发生循环依赖的呢?,接下来就让我 ...

  6. Spring — 循环依赖

    读完这篇文章你将会收获到 Spring 循环依赖可以分为哪两种 Spring 如何解决 setter 循环依赖 Spring 为何是三级缓存 , 二级不行 ? Spring 为啥不能解决构造器循环依赖 ...

  7. 3.1 spring5源码系列--循环依赖 之 手写代码模拟spring循环依赖

    本次博客的目标 1. 手写spring循环依赖的整个过程 2. spring怎么解决循环依赖 3. 为什么要二级缓存和三级缓存 4. spring有没有解决构造函数的循环依赖 5. spring有没有 ...

  8. Spring循环依赖原理

    Spring循环依赖的原理解析 1.什么是循环依赖? ​ 我们使用Spring的时候,在一个对象中注入另一个对象,但是另外的一个对象中也包含该对象.如图: 在Student中包含了teacher的一个 ...

  9. Spring循环依赖的解决

    ## Spring循环依赖的解决 ### 什么是循环依赖 循环依赖,是依赖关系形成了一个圆环.比如:A对象有一个属性B,那么这时候我们称之为A依赖B,如果这时候B对象里面有一个属性A.那么这时候A和B ...

  10. spring 循环依赖的一次 理解

    前言: 在看spring 循环依赖的问题中,知道原理,网上一堆的资料有讲原理. 但今天在看代码过程中,又产生了疑问. 疑问点如下: // 疑问点: 先进行 dependon 判断String[] de ...

随机推荐

  1. 反射:获取Class 类的实例(四种方法)

    Class 类  对象照镜子后可以得到的信息:某个类的属性.方法和构造器.某个类到底实现了哪些接口.对于每个类而言,JRE 都为其保留一个不变的 Class 类型的对象.一个 Class 对象包含了 ...

  2. 0415-File类和FileFilter接口

    package demoFile; import java.io.File; import java.io.FileFilter; import java.io.FilenameFilter; imp ...

  3. flutter run出现 Deprecated Gradle features were used in this build, making it incompatible with Gradle 7.0.

    1 今天flutter run出现下面这样的情况 > Task :prepareKotlinBuildScriptModel UP-TO-DATE Deprecated Gradle featu ...

  4. Flink同步mysql到iceberg

    一.如何做一致性保障 1.全量数据分片读取,增量数据单并发读取,保证增量阶段不会乱序2.全量阶段写入失败会清空表后重新写入,避免重复数据.3.全量阶段多task并行读取,把每个task开始结束时间提交 ...

  5. 大数据HDFS集群相关概念

    一.Zookeeper服务 端口 描述 配置路径 2181 主要使用端口,对cline端提供服务.连接方式jdbc:hive2://ip:2181 conf/zoo.cfg中clientPort 21 ...

  6. 推荐一款人人可用的开源 BI 工具,更符合国人使用习惯的数据可视化分析工具,数据大屏开发神器!

    前言 今天大姚给大家推荐一款人人可用的开源.免费的 BI 工具,更符合国人使用习惯的数据可视化分析工具,数据大屏开发神器,Tableau.帆软的开源替代:DataEase. 工具介绍 DataEase ...

  7. 2023LN省选游记

    前言 CSP第一轮都考完了,我才写这个游记.我真懒惰 书接上回 正文 Day -114514 我也没想到我居然能报省选. 报上了.准备去爆零. Day -114513~Day -1 学习暴力算法以及痛 ...

  8. 别再为文本提取抓狂!一站式文本提取神器Kreuzberg 助你解决PDF、图片、文档等多格式文件的文本提取难题

    大家好,我是六哥,相信很多朋友肯定都有过从各种文档里提取文本的经历,那过程可太让人头疼了!今天就给大家分享一款超实用的现代Python库--Kreuzberg,帮你轻松解决文本提取的难题. 一.Kre ...

  9. 解决黑群晖 Docker 日志八小时时间差的有效方法

    步骤一:登录黑群晖控制台 首先,我们需要登录到黑群晖控制台.可以通过SSH登录,或是直接在黑群晖控制台界面上操作. 步骤二:停止相关的Docker容器 在解决时间差问题之前,我们需要停止相关的Dock ...

  10. windows 配置java发布环境

    一.jdk安装 1.下载jdk安装文件 2.在"系统变量"下"新建"选项"JAVA_HOME"值为:"jdk"文件夹路径 ...