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. UTS Open '21 P7 - April Fools

    传送门 前言 本题是笔者keysky与同学yangbaich讨论+推式子一整个晚上以及讨论前ybc的一整个下午做出来的,综合起来是 \(34\) 个转移方程,对于整道题来说,贡献大抵为我 \(2\) ...

  2. C# Dev GridView当前行

    DEV获取GridControl当前行 //直接通过gridView获取当前行 dr=this.gridView1.GetDataRow(this.gridView1.FocusedRowHandle ...

  3. 微信小程序上拉触底事件onReachBottom不触发的解决方案

    1.配置属性问题 //设置容器高度为100% page{ height: 100% } 2. 切换页面时 滚动条滚回到顶部 //切换页面时调用API wx.pageScrollTo({ scrollT ...

  4. C盘扩展卷碰到的那些事-->不是同一块物理磁盘操作扩展卷是有坑的

    自己电脑上面用过win10系统资源管理器扩展卷的功能,用过几次都成功扩容了磁盘空间,简单说一下原理: 就是将剩余未分配的磁盘空间划给要扩展的磁盘. 这天公司的电脑C盘老是红色提示空间不足,那就扩充容量 ...

  5. 腾讯元宝接入 DeepSeek R1 模型,支持深度思考 + 联网搜索,好用不卡机!

    前言 腾讯元宝AI产品于2025年2月13日在应用商店发布更新,正式接入了DeepSeek R1模型,并宣布该模型已联网.满血上线,DeepSeek+腾讯混元,好用不卡机. 腾讯元宝介绍 腾讯元宝是依 ...

  6. 程序员转型AI:行业分析

    系列目录 1.程序员转型AI:行业分析 2.程序员转型AI:转型计划 3.程序员转型AI:落地实践 4.程序员转型AI:展望未来 一.背景分析 进入2025年,AI已经爆发式增长,且进入实际商业变现阶 ...

  7. KUKA库卡机器人维修

    KUKA库卡机器人作为生产线上的核心设备,一旦出现KUKA机械手故障,将直接影响整个生产线的运行效率.及时的库卡机器人维修工作不仅能够迅速恢复机器人的工作状态,减少生产停滞时间,还能通过预防性维护降低 ...

  8. SignalR 外部调用自定义Hub类的方法,Clients为null

    这是因为外部调用的类的对象和你连接的Hub类的对象,这两个对象 不!一!样! 解决方法 在自定义的Hub类中,注入IHubContext对象,然后在方法中调用IHubContext对象来向前端推送数据 ...

  9. 大数据之路Week10_day05 (Redis总结I)

    正文 1.为什么使用redis 分析:博主觉得在项目中使用redis,主要是从两个角度去考虑:性能和并发.当然,redis还具备可以做分布式锁等其他功能,但是如果只是为了分布式锁这些其他功能,完全还有 ...

  10. [第二章]ABAQUS CM插件中文手册

    ABAQUS Composite Modeler User Manual(zh-CN) Dassault Systèmes, 2018 注: 源文档的交叉引用链接,本文无效 有些语句英文表达更易理解, ...