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. Python · Jax | 在 python 3.8 上安装 jax,运行 offline RL 的 IQL

    致谢师兄的 jax 环境,完全按照师兄的 conda_env.yml 配置的 (如何导出其他环境的 conda_env.yml:Conda | 如何(在新服务器上)复制一份旧服务器的 conda 环境 ...

  2. 存储过程专题(Oracle)

    本文转自 https://www.cnblogs.com/lukelook/p/9600407.html,感谢博主 豆豆DE思念 整理分享. 1.Oracle 存储过程基本格式  最简单的版本 is ...

  3. Keepalived基本原理

    本文分享自天翼云开发者社区<Keepalived基本原理>,作者:Ujnrfc Keepalived简介 Keepalived是Linux下一个轻量级别的高可用解决方案.高可用:广义来讲, ...

  4. 登上国际舞台!天翼云P4 EIP网关流量管理创新方案亮相CCGrid 2024!

    5月8日,第24届IEEE/ACM集群.云和互联网计算国际研讨会(CCGrid 2024)在美国费城隆重举行.来自中国.美国.印度.法国等国家的学术及产业界代表齐聚一堂,围绕云计算相关议题进行深入探讨 ...

  5. 这期没有 AI 开源项目「GitHub 热点速览」

    最近 GitHub 上的 AI 开源项目扎堆,几乎到了"刷屏"的程度.所以这次我们换个口味,来看看那些非 AI.有趣的开源项目! Rust 不好学呀!尤其是所有权和生命周期这些概念 ...

  6. 松下机器人示教器AUR01062触摸无反维修

    Panasonic松下机器人示教器AUR01062触摸无反应解决方案 松下机器人示教器现象:触摸屏幕时鼠标箭头无任何动作,没有发生位置改变. 原因:造成此现象产生的原因很多,下面就松下机器人维修中示教 ...

  7. SQL取系统时间的前一个月的月份和年份

    SQL SERVER 提供了一些时间函数:取当前时间:select getdate()取前一个月的时间:SELECT DATEADD(MONTH,-1,GETDATE()) 月份减一个月取年份:SEL ...

  8. 13. MySQL 事务基础知识(详细说明实操剖析)

    13. MySQL 事务基础知识(详细说明实操剖析) @ 目录 13. MySQL 事务基础知识(详细说明实操剖析) 1. 数据库事务概述 1.1 存储引擎支持情况 1.2 事务基本概念 1.3 事务 ...

  9. SIT、UAT以及PROD环境的区别

    题记部分 一.SIT环境   SIT(System Integration Testing)环境主要用于系统集成测试,旨在验证系统中不通模块之间的集成和交互是否正常工作.这个环境通常用于开发团队内部进 ...

  10. sql server 使用sql语句导出二进制文件到本地磁盘

    sp_configure 'show advanced options', 1;GORECONFIGURE;GOsp_configure 'Ole Automation Procedures', 1; ...