spring为什么要用三级缓存而不是二级缓存
singletonFactory.getObject()每次会生成不同的代理对象,如果没有二级缓存,直接放在一级缓存不行,一级缓存放的是已经初始化完毕的 Bean。所以必须有个二级缓存,当再次调用singletonFactory.getObject()的时候从二级缓存里拿之前的代理对象
在 Spring 中,当涉及到 AOP 代理对象的创建时,可能会面临循环依赖的问题,即一个 Bean 的创建依赖于另一个 Bean,而这两个 Bean 又相互依赖。这时引入三级缓存的机制可以帮助解决循环依赖的问题。让我们详细解释一下为什么三级缓存能够解决 AOP 循环依赖:
-
两级缓存的问题:
- singletonObjects(一级缓存): 存储完全初始化的 Bean 实例。
- earlySingletonObjects(二级缓存): 存储正在创建过程中但尚未完全初始化的 Bean 实例。
如果只有这两级缓存,可能会在 AOP 代理对象的创建过程中遇到问题。当 AOP 代理对象依赖于其他 Bean,并且这些 Bean 又依赖于 AOP 代理对象时,可能会导致死锁或引用不正确的实例。因为
singletonObjects
存储的是完全初始化的实例,而代理对象的创建中涉及到尚未完全初始化的 Bean。 -
三级缓存的解决方案:
- singletonObjects(一级缓存): 仍然存储完全初始化的 Bean 实例。
- earlySingletonObjects(二级缓存): 仍然存储正在创建过程中但尚未完全初始化的 Bean 实例。
- singletonFactories(三级缓存): 存储 Bean 工厂,用于在创建代理对象的过程中提供尚未初始化的实例。
当 AOP 代理对象的创建涉及到其他 Bean,并且这些 Bean 又依赖于 AOP 代理对象时,
singletonFactories
就发挥了作用。它存储的是 Bean 工厂,即尚未完成初始化的 Bean。在代理对象的创建过程中,可以通过singletonFactories
提前获取到尚未初始化的实例,避免了死锁和循环依赖的问题。这三级缓存机制确保了在代理对象的创建过程中,能够在不同阶段提供正确的引用,避免了循环依赖可能带来的问题。这是 Spring IoC 容器处理复杂依赖关系的一种机制,特别是在 AOP 场景下更为显著。
Spring为什么不使用二级缓存?Spring 动态代理时是如何解决循环依赖的?为什么要使用三级缓存?... - 知乎 (zhihu.com)
本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。 如若内容造成侵权/违法违规/事实不符,请联系我的编程经验分享网邮箱:veading@qq.com进行投诉反馈,一经查实,立即删除!