当前位置: 代码网 > it编程>编程语言>Java > Spring中的循环依赖问题

Spring中的循环依赖问题

2024年09月18日 Java 我要评论
在 spring 中,循环依赖是指两个或多个 bean 相互依赖,导致在创建过程中出现了依赖死锁的问题。为了解决循环依赖,spring 引入了三级缓存机制。了解为什么需要三级缓存机制,首先要明白循环依

在 spring 中,循环依赖是指两个或多个 bean 相互依赖,导致在创建过程中出现了依赖死锁的问题。

为了解决循环依赖,spring 引入了三级缓存机制。

了解为什么需要三级缓存机制,首先要明白循环依赖是如何发生的,以及两级缓存为什么不足够。

一、循环依赖是什么?

假设有两个 bean ab

  • a 依赖于 b
  • b 依赖于 a

如果没有缓存机制,spring 在创建 a 时会发现它需要 b,于是去创建 b,但在创建 b 时又发现需要 a,这时就会产生循环依赖,最终导致栈溢出或抛出异常。

二、三级缓存机制

spring 使用三级缓存(三级依赖处理机制)来解决循环依赖问题,分别是:

一级缓存singletonobjects

  • 用于存储完全初始化好的单例对象。
  • 完全初始化后的 bean 会放入一级缓存中,表示该 bean 已经准备好可以使用了。

二级缓存earlysingletonobjects

  • 用于存储提前暴露的 bean,主要是尚未完成依赖注入但已经实例化的 bean。
  • 这个缓存用于提前暴露尚未完成初始化的 bean,防止循环依赖无法解决。通常情况下,如果某个 bean 已经实例化但还没有完成后续的属性填充等操作,它会存放在这个缓存中。

三级缓存singletonfactories

  • 用于存储 bean 的 objectfactory(对象工厂),这个工厂提供对该 bean 的代理对象(比如 aop 代理对象)的创建逻辑。
  • 三级缓存的存在使得 spring 可以在 bean 创建的早期阶段将未完全初始化的 bean 提供出来,尤其是代理对象。这样即使 bean 还没有完成依赖注入,也能通过工厂获得它的一个早期引用。

三、为什么需要三级缓存?两级不行吗?

假如只使用一级缓存和二级缓存:

  • 一级缓存只存储已经完全初始化好的 bean,显然无法解决循环依赖问题,因为 bean 尚未完成初始化时无法放入一级缓存。
  • 二级缓存则存储提前暴露的 bean,但这通常是直接的原始对象,而不是代理对象。如果应用了 aop 或者需要创建代理对象的场景中,依赖的 bean 如果在循环依赖中被提前暴露时,可能无法应用正确的代理。

三级缓存 允许通过 objectfactory 这种延迟加载的方式,在需要的时候创建早期引用,包括创建代理对象。这确保了即使在循环依赖中,spring 也可以在合适的时间点创建完整的代理对象,而不是仅仅提供原始对象。

总结

三级缓存机制的关键点在于:

  • 二级缓存不能解决 bean 代理的问题,特别是在涉及到 aop 的情况下。
  • 三级缓存通过引入 objectfactory,可以确保在代理场景下也能处理循环依赖,提前暴露还未完全初始化的代理对象。

因此,两级缓存不足以解决所有循环依赖问题,特别是在涉及到代理对象的情况下,三级缓存的机制显得非常必要。

以上为个人经验,希望能给大家一个参考,也希望大家多多支持代码网。

(0)

相关文章:

版权声明:本文内容由互联网用户贡献,该文观点仅代表作者本人。本站仅提供信息存储服务,不拥有所有权,不承担相关法律责任。 如发现本站有涉嫌抄袭侵权/违法违规的内容, 请发送邮件至 2386932994@qq.com 举报,一经查实将立刻删除。

发表评论

验证码:
Copyright © 2017-2025  代码网 保留所有权利. 粤ICP备2024248653号
站长QQ:2386932994 | 联系邮箱:2386932994@qq.com