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)

相关推荐
颜进强1 分钟前
04 · NestJS 依赖注入:你在 `@Module` 写的 providers,和构造参数里那个类型,是怎么"对上"的?
前端·后端·ai编程
MayBaymax3 分钟前
MongoDB 索引与事务
java·数据库·mongodb
vx-程序开发10 分钟前
【计算机毕设】django校园跑腿服务系统83141
java·数据库·vue.js·spring boot·spring·elasticsearch·django
谁在黄金彼岸13 分钟前
Ollama-使用速查
后端
ServBay13 分钟前
Jev是什么?哑巴模型居然全网爆火
后端·aigc·ai编程
勇气要爆发28 分钟前
006.注解
java·注解
烈风逍遥29 分钟前
第六篇:RAG 知识库构建与检索全链路
前端·人工智能·后端
花椒技术30 分钟前
Agent 沙箱怎么接入生产?花椒的选型、持久化与执行协议实践
人工智能·后端·agent
liuchangng36 分钟前
Jev 模型研究:从生成式大模型到决策式模型——System One、RLCD 校准与采用边界
java·javascript·人工智能·python·深度学习
GPU实战笔记37 分钟前
本地跑不动 llama.cpp,临时租云 GPU 怎么搭?从启动服务到环境复用
java·服务器·网络·人工智能·深度学习·llama