文章详情

短信预约-IT技能 免费直播动态提醒

请输入下面的图形验证码

提交验证

短信预约提醒成功

想进阿里?先搞懂Spring Bean的循环依赖!

2024-11-30 00:11

关注

图片

什么是循环依赖?

循环依赖,作为软件开发中常见的问题之一,指的是两个或多个组件之间形成了相互依赖的关系,最终形成一个循环。在编程领域中,这种情况可能会导致程序运行时出现一系列难以预料的问题,比如死锁、无限递归等。

循环依赖通常出现在对象之间相互引用的场景中。举个简单的例子,假设有两个类A和B,A中引用了B,而B中又引用了A,这样就形成了循环依赖。在实际开发中,循环依赖可能会导致程序的初始化顺序混乱,或者造成内存泄漏等问题。

Spring中循环依赖场景

在Spring框架中,循环依赖是指两个或多个Bean之间存在相互依赖的情况,这在日常开发中是比较常见的。下面我们来详细了解一下在Spring中的循环依赖场景以及可能的解决方案。

首先,让我们看看Spring中几种典型的循环依赖场景:

以上这些场景都有可能导致Spring容器在初始化Bean时出现循环依赖的情况,从而引发一系列问题,比如Bean无法正常初始化、内存溢出等。

其中,构造器的循环依赖问题无法解决,在解决属性循环依赖时,可以使用懒加载,spring采用的是提前暴露对象的方法。

懒加载解决循环依赖问题

懒加载(Lazy initialization)是Spring框架提供的一种解决循环依赖问题的有效策略之一,其中通过使用@Lazy注解来延迟Bean的初始化过程。在循环依赖的情况下,如果两个Bean相互依赖,可能会导致初始化过程中出现死锁或无限递归等问题。通过懒加载的方式,Spring容器会将Bean的初始化推迟到第一次被调用时才进行,从而避免了循环依赖导致的初始化问题。

举例来说,假设我们有两个Bean:Bean A 和 Bean B,它们相互依赖。通过在Bean的定义中添加@Lazy注解,告诉Spring容器在初始化时不要立即创建Bean的实例,而是等到需要使用该Bean时再进行初始化。这样可以确保Bean在初始化过程中不会出现循环依赖的问题。

虽然懒加载能够有效解决循环依赖问题,但也需要注意一些潜在的性能影响。因为每次使用Bean时都需要进行初始化,所以可能会增加一定的延迟和资源消耗。因此,在使用懒加载时需要根据具体情况权衡考虑,选择合适的解决方案。

三级缓存解决循环依赖问题

三级缓存是Spring框架用来解决循环依赖问题的重要机制之一。在面对循环依赖的情况下,Spring会使用三级缓存来管理Bean的创建过程,确保循环依赖不会导致程序出现异常或无限递归。

这个机制涉及到三个缓存阶段:singletonObjects、earlySingletonObjects和singletonFactories。

首先,当Spring容器创建Bean时,会将正在创建的Bean放入singletonFactories缓存中。接着,Spring会调用Bean的构造函数创建实例,并将实例放入earlySingletonObjects缓存中,此时Bean还未完全初始化,可能存在一些未完成的依赖。最后,Spring会完成Bean的初始化,解决所有的依赖关系,并将完全初始化的Bean放入singletonObjects缓存中。

当另一个Bean依赖正在创建的Bean时,Spring会先从singletonObjects缓存中尝试获取Bean的实例,如果获取不到,则会从earlySingletonObjects缓存中获取。如果依然无法获取到,则说明Bean还未完全初始化,此时Spring会检查singletonFactories缓存中是否有正在创建的Bean的工厂实例。如果有,则会等待Bean的完全初始化,从而解决循环依赖。

如果检测到循环依赖无法解决,Spring会抛出相应的异常,比如BeanCurrentlyInCreationException,通知开发者存在循环依赖问题。

通过三级缓存机制,Spring能够在容器初始化过程中管理Bean的创建顺序,并确保循环依赖不会导致程序出现异常。但是需要注意的是,过多的循环依赖可能会导致性能下降,因此在设计应用程序时应尽量避免过多的循环依赖。

为什么是三级缓存而不是二级?

你可能会好奇为什么Spring使用了三级缓存而不是二级。首先,让我们来理解一下什么是二级缓存。在二级缓存的情况下,Spring容器会将正在创建的Bean实例放入一个缓存中,用于管理正在创建的Bean。当另一个Bean需要引用正在创建的Bean时,容器会先从这个缓存中尝试获取Bean的实例,以解决循环依赖的问题。

然而,如果仅仅使用二级缓存,可能会遇到一些问题。主要有以下几个方面:

因此,为了解决这些问题,Spring引入了三级缓存机制。三级缓存在二级缓存的基础上增加了一个缓存阶段,即earlySingletonObjects,用于存储已经创建但尚未完成初始化的Bean实例。通过这样的设计,Spring能够更好地管理Bean的创建过程,确保循环依赖不会导致程序出现异常。


来源:知其然亦知其所以然内容投诉

免责声明:

① 本站未注明“稿件来源”的信息均来自网络整理。其文字、图片和音视频稿件的所属权归原作者所有。本站收集整理出于非商业性的教育和科研之目的,并不意味着本站赞同其观点或证实其内容的真实性。仅作为临时的测试数据,供内部测试之用。本站并未授权任何人以任何方式主动获取本站任何信息。

② 本站未注明“稿件来源”的临时测试数据将在测试完成后最终做删除处理。有问题或投稿请发送至: 邮箱/279061341@qq.com QQ/279061341

软考中级精品资料免费领

  • 历年真题答案解析
  • 备考技巧名师总结
  • 高频考点精准押题
  • 2024年上半年信息系统项目管理师第二批次真题及答案解析(完整版)

    难度     813人已做
    查看
  • 【考后总结】2024年5月26日信息系统项目管理师第2批次考情分析

    难度     354人已做
    查看
  • 【考后总结】2024年5月25日信息系统项目管理师第1批次考情分析

    难度     318人已做
    查看
  • 2024年上半年软考高项第一、二批次真题考点汇总(完整版)

    难度     435人已做
    查看
  • 2024年上半年系统架构设计师考试综合知识真题

    难度     224人已做
    查看

相关文章

发现更多好内容

猜你喜欢

AI推送时光机
位置:首页-资讯-后端开发
咦!没有更多了?去看看其它编程学习网 内容吧
首页课程
资料下载
问答资讯