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)

相关推荐
武大打工仔3 分钟前
从零开始手搓一个MVC框架
后端
开心猴爷8 分钟前
移动端网页调试实战 Cookie 丢失问题的排查与优化
后端
kaika18 分钟前
告别复杂配置!使用 1Panel 运行环境功能轻松搭建 Java 应用
java·1panel·建站·halo
用户5724056148 分钟前
解析Json
后端
舒一笑9 分钟前
Mac 上安装并使用 frpc(FRP 内网穿透客户端)指南
后端·网络协议·程序员
每天学习一丢丢15 分钟前
Spring Boot + Vue 项目用宝塔面板部署指南
vue.js·spring boot·后端
邹小邹15 分钟前
Go 1.25 强势来袭:GC 速度飙升、并发测试神器上线,内存检测更精准!
后端·go
有梦想的攻城狮16 分钟前
Java 11中的Collections类详解
java·windows·python·java11·collections
lichenyang45319 分钟前
管理项目服务器连接数据库
数据库·后端
生无谓21 分钟前
在Windows系统上安装多个JDK版本并切换
后端