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. C# WebAPI 插件热插拔

    背景 WebAPI 插件热插拔是指在不重启应用程序的情况下,能够动态地加载.更新或卸载功能模块(即插件)的能力.这种设计模式在软件开发中非常有用,尤其是在需要频繁更新或扩展功能的大型系统中.通过实现插 ...

  2. RocketMQ原理—5.高可用+高并发+高性能架构

    大纲 1.RocketMQ的整体架构与运行流程 2.基于NameServer管理Broker集群的架构 3.Broker集群的主从复制架构 4.基于Topic和Queue实现的数据分片架构 5.Bro ...

  3. 通讯录管理系统(C++基础知识实现)

    通讯录管理系统 描述:本人C++小白一枚,正在学习C++基础知识,给大家分享一款使用C++基础知识实现的通讯录管理系统,一起努力进步,大佬轻点喷. 1. 知识点 (1) 预处理器指令 (#includ ...

  4. Mac常用系统配置

    一.系统类 1.隐藏文件夹 打开控制台输入:chflags hidden [拖入需要隐藏的文件夹] 2.特定软件触控栏一直显示F1-F12 选择左上角苹果->系统设置->键盘-> 3 ...

  5. 1个小技巧彻底解决DeepSeek服务繁忙!

    DeepSeek 是国内顶尖 AI 团队「深度求索」开发的多模态大模型,具备数学推理.代码生成等深度能力,堪称"AI界的六边形战士". DeepSeek 最具代表性的标签有以下两个 ...

  6. 我把deepseek等大模型接入了微信公众号,打造个人AI助手

    前言 最近deepseek大模型可是火出了圈,给国产大模型公司点赞.于是乎去deepseek试了一下效果,奈何太多人使用了,问两句来一句 "服务器繁忙,请稍后再试",体验感实在太差 ...

  7. 从0搭建Vue3组件库(一): 开篇

    前言 这是从0搭建Vue3组件库系列文章第一篇文章,这个系列我曾经写过多篇文章,但是写完之后回过头来再看里面有很多遗漏以及不足之处,所以决定重新梳理这个系列,并从头开始搭建一个完整的Vue3组件库工程 ...

  8. datawhale-leetcode打卡:001-012题

    这次这十二个题目属于是极限肝出来的,有两个参考了一下题解,还是很有意思.我会按照我个人的感觉去写这个东西. 螺旋矩阵(leetcode 054) 这个题目比较恶心的就是跑圈的过程怎么描述.首先,顺时针 ...

  9. Ollama 模型迁移备份工具 ollamab

    背景 ollama 模型和相关配置文件默认都放在 models 文件夹下,想要把指定模型迁移到其他电脑比较麻烦,所以就有了该工具.还有就是模型下载本身就慢,一次下载多台使用减少下载次数.最重要的是公司 ...

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

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