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)

相关推荐
Sirius Wu1 分钟前
Channel如何安全地尝试发送数据
后端·golang
liyongqiangcc7 分钟前
微服务之间有哪些调用方式?
后端
苍煜24 分钟前
MinIO 教程:从入门到Spring Boot集成
java·spring boot·后端·minio
掘金詹姆斯25 分钟前
LangChain4j—持久化聊天记忆 Persistence(五)
java·人工智能
嘻嘻嘻嘻嘻嘻ys26 分钟前
《Vue 3全栈架构实战:Vite工程化、Pinia状态管理与Nuxt 3深度解析》
前端·后端
chaowwwww33 分钟前
代码的圈复杂度和认知复杂度
后端
uhakadotcom38 分钟前
如何用AI打造高效招聘系统,HR效率提升100%!
后端·算法·面试
程序猿大波39 分钟前
基于Java,SpringBoot,Vue,HTML宠物相亲配对婚恋系统设计
java·vue.js·spring boot
努力的IT小胖子1 小时前
Docker 镜像下载太慢?手把手教你修改镜像源,速度起飞!
后端·docker·容器
无业哥1 小时前
Mac搭建Spring5源码环境
spring