spring为什么要用三级缓存而不是二级缓存

singletonFactory.getObject()每次会生成不同的代理对象,如果没有二级缓存,直接放在一级缓存不行,一级缓存放的是已经初始化完毕的 Bean。所以必须有个二级缓存,当再次调用singletonFactory.getObject()的时候从二级缓存里拿之前的代理对象

在 Spring 中,当涉及到 AOP 代理对象的创建时,可能会面临循环依赖的问题,即一个 Bean 的创建依赖于另一个 Bean,而这两个 Bean 又相互依赖。这时引入三级缓存的机制可以帮助解决循环依赖的问题。让我们详细解释一下为什么三级缓存能够解决 AOP 循环依赖:

  1. 两级缓存的问题:

    • singletonObjects(一级缓存): 存储完全初始化的 Bean 实例。
    • earlySingletonObjects(二级缓存): 存储正在创建过程中但尚未完全初始化的 Bean 实例。

    如果只有这两级缓存,可能会在 AOP 代理对象的创建过程中遇到问题。当 AOP 代理对象依赖于其他 Bean,并且这些 Bean 又依赖于 AOP 代理对象时,可能会导致死锁或引用不正确的实例。因为 singletonObjects 存储的是完全初始化的实例,而代理对象的创建中涉及到尚未完全初始化的 Bean。

  2. 三级缓存的解决方案:

    • singletonObjects(一级缓存): 仍然存储完全初始化的 Bean 实例。
    • earlySingletonObjects(二级缓存): 仍然存储正在创建过程中但尚未完全初始化的 Bean 实例。
    • singletonFactories(三级缓存): 存储 Bean 工厂,用于在创建代理对象的过程中提供尚未初始化的实例。

    当 AOP 代理对象的创建涉及到其他 Bean,并且这些 Bean 又依赖于 AOP 代理对象时,singletonFactories 就发挥了作用。它存储的是 Bean 工厂,即尚未完成初始化的 Bean。在代理对象的创建过程中,可以通过 singletonFactories 提前获取到尚未初始化的实例,避免了死锁和循环依赖的问题。

    这三级缓存机制确保了在代理对象的创建过程中,能够在不同阶段提供正确的引用,避免了循环依赖可能带来的问题。这是 Spring IoC 容器处理复杂依赖关系的一种机制,特别是在 AOP 场景下更为显著。

Spring为什么不使用二级缓存?Spring 动态代理时是如何解决循环依赖的?为什么要使用三级缓存?... - 知乎 (zhihu.com)

相关推荐
鬼先生_sir4 分钟前
SpringBoot-源码剖析
java·spring boot·springboot源码解析
ch.ju6 分钟前
Java程序设计(第3版)第二章——Java中的数据类型
java
MwEUwQ3Gx7 分钟前
深入理解 Java Deque 的设计哲学
java·开发语言·python
麦芽糖02197 分钟前
若依整合AI一 基础应用篇
java
进朱者赤8 分钟前
从 Java / Go 后端视角系统理解 TypeScript 与 Node.js:从看不懂到能参与 openclaw 这类项目开发
java·golang·typescript
MX_93599 分钟前
SpringMVC静态资源访问、annotation-driven的使用原理及数据响应模式
java·后端·spring
人间寥寥情难诉11 分钟前
LRU算法本地实现
java·算法·spring
djBe17esS12 分钟前
实战:Java 日志中打印服务器 IP,快速区分多服务器日志归属
java·服务器·tcp/ip
woai336414 分钟前
JVM学习-基础篇-垃圾回收
java·jvm·学习
七夜zippoe18 分钟前
应用安全实践(一):常见Web漏洞(OWASP Top 10)与防护
java·前端·网络·安全·owasp