java中的循环依赖以及解决方案

这篇具有很好参考价值的文章主要介绍了java中的循环依赖以及解决方案。希望对大家有所帮助。如果存在错误或未考虑完全的地方,请大家不吝赐教,您也可以点击"举报违法"按钮提交疑问。

java中的循环依赖以及解决方案

什么是循环依赖

我们创建了两个类,一个类A,一个类B(当然循环依赖不一定只是两个类,可能是多个以及以上的类),在A里面引入了B,在B里面引入了A,这时候就构成了一个循环问题,看似无止境,无尽头
java中的循环依赖以及解决方案
他们之间的关系如下
java中的循环依赖以及解决方案

spring循环依赖解决方案

这些类在我们spring框架启动的时候,会进行有序的扫描并实例化
拿A举例:
1.实例化A
2.将a对象放入到指定的三级缓存对象
3.setName…当到成员变量b的时候,发现B上面有@Atowired注解,就会触发B的实例化过程

  • 实例化B
  • 将b对象放入到指定的三级缓存对象
  • setName…当到成员变量a的时候,就会去spring的三级缓存里面直接去拿
  • B的实例化完成

4.拿到b的实例化对象

注意:构造器注入构成的循环依赖是无法解决的!只能抛出BeanCurrentlyInCreationException异常表示循环依赖,构造函数之间发生循环依赖(A的构造方法中依赖B,B的构造方法中依赖A),程序会在运行时一直循环调用最终导致内存溢出。
错误原因:
根本原因是 Spring 解决循环依赖依靠的是 Bean 的 中间态 这个概念,而中间态指的是 已经实例化,但未初始化的状态。而构造器负责的是实例化,故无法解决构造器循环依赖。

spring的三级缓存

在Spring框架中,有一个名为"三级缓存"(Three-level Cache)的概念,用于管理Bean的创建和解决循环依赖的问题。

三级缓存是指在Spring容器实例化Bean的过程中,使用了三个缓存来管理Bean的创建和依赖关系。具体来说,这三个缓存分别是singletonObjects、earlySingletonObjects和singletonFactories。

singletonObjects:这是一级缓存,用于保存已经完全初始化的单例Bean的实例。当Bean创建完成后,它将被放入此缓存中,并且可以通过Bean名称进行访问。

earlySingletonObjects:这是二级缓存,用于保存已经实例化但尚未完全初始化的单例Bean的实例。当Spring框架检测到循环依赖时,会首先将已实例化但未初始化的Bean放入该缓存中,以便后续的依赖注入。一旦所有的依赖都已注入完成,Bean将从此缓存中移除,并放入一级缓存中。

singletonFactories:这是三级缓存,用于保存Bean的工厂类实例。当Spring框架检测到循环依赖时,会先创建一个Bean的工厂类实例并放入该缓存中。这样,当另一个Bean需要引用该Bean时,可以通过工厂类来获取实例,并在后续的实例化过程中完成循环依赖。

通过使用这三个级别的缓存,Spring框架可以在解决循环依赖问题时进行适当的处理,确保Bean的实例化和依赖注入的顺序正确。同时,三级缓存也有助于提高性能,避免重复创建Bean实例。但需要注意的是,三级缓存是Spring框架内部使用的机制,对开发者来说通常是透明的,不需要直接操作或干预。

在Java中,使用三级缓存是解决循环依赖问题的一种方案,通常被称为"提前暴露引用(Early Reference)"方案。

循环依赖是指两个或多个Bean之间相互依赖的情况,在实例化过程中可能会造成死锁或无法正确注入依赖的问题。为了解决这个问题,Spring框架引入了三级缓存机制,并且使用"提前暴露引用"的方式来处理循环依赖。

"提前暴露引用"方案的基本思想是,在实例化Bean的过程中,先创建一个早期的、未完全初始化的Bean实例,并将其放入二级缓存中。然后,在完成当前Bean的依赖注入之后,再从二级缓存中取出该早期实例并进行初始化。这样,可以通过提前暴露引用的方式解决循环依赖的问题。

在三级缓存中的三个级别,二级缓存即为保存早期实例的缓存,通过它来实现"提前暴露引用"的方案。当依赖注入完成后,早期实例会转移到一级缓存中,而三级缓存中的工厂类实例则会被移除。

需要注意的是,三级缓存和"提前暴露引用"方案都是Spring框架内部实现的,对于开发者来说通常是透明的。开发者只需按照正常的依赖关系进行编码,Spring框架会根据三级缓存机制来解决循环依赖问题。文章来源地址https://www.toymoban.com/news/detail-445941.html

到了这里,关于java中的循环依赖以及解决方案的文章就介绍完了。如果您还想了解更多内容,请在右上角搜索TOY模板网以前的文章或继续浏览下面的相关文章,希望大家以后多多支持TOY模板网!

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处: 如若内容造成侵权/违法违规/事实不符,请点击违法举报进行投诉反馈,一经查实,立即删除!

领支付宝红包 赞助服务器费用

相关文章

  • Redis中的缓存穿透、雪崩、击穿的原因以及解决方案

    是指用户查询数据,在数据库没有,自然在缓存中也不会有。这样就导致用户查询的时候,在缓存中找不到,每次都要去数据库再查询一遍,然后返回空(相当于进行了两次无用的查询)。这样请求就绕过缓存直接查数据库,这也是经常提的缓存命中率问题。 我们可以简单的

    2024年02月12日
    浏览(31)
  • Java 常见缓存详解以及解决方案

    首先我们准备一个接口 两个实现的方法, 当我们调用这个queryAll()方法时我们需要调用selectAll()方法来查询数据  调用此接口实现效果  这个时候我们就可以发现了问题,我们调用方法之后对数据库查询了两次,但是只有一次请求这样进行了多次查询,造成了资源的浪费

    2024年01月25日
    浏览(31)
  • Java中的死锁及其解决方案

    在Java中,锁是很常见的一个工具,常见的用法就是在高并发场景下保证线程安全,但是使用不当也会造成死锁,给我们带来一些不必要的麻烦,本文分析死锁及其产生原因,并作出相应的解决方案。 死锁产生的四个必要条件 1)互斥条件:进程对所分配到的资源进行排他性控

    2024年02月07日
    浏览(30)
  • spring 的循环依赖以及spring为什么要用三级缓存解决循环依赖

            bean的生命周期         这里简单过一下 class -无参构造 -普通对象 -依赖注入(对加了autowire等的属性赋值) -初始化前-初始化 -初始化后(aop) -放入单例池的map(一级缓存) -bean对象 这里提一点单例bean单例bean 其实就是用mapbeanName,Bean对象创建的,多例bean就不

    2024年02月15日
    浏览(40)
  • sql中的时间范围查询【三种方式】以及Mapper.xml中遇到大于号小于号问题解决方案

    mapper注意事项 字符 转义字符 描述 gt; 大于 = gt;= 大于等于 lt; 小于 = lt;= 小于等于 \\\" quot; 双引号 ’ apos; 单引号 amp; and 遇到问题: 从数据库获取时间传到前端进行展示的时候,我们有时候可能无法得到一个满意的时间格式的时间日期,在数据库中显示的是正确的时间格式,获

    2024年02月10日
    浏览(34)
  • Java中的单点登录原理与实现方案探究:深入了解安全与便捷的用户认证解决方案

    目录 1、什么是单点登录 2、单点登录的优势和应用场景 3、单点登录的原理和实现方式 3.1 传统的Cookie和Session实现方式 3.2 基于Token的实现方式 3.3 基于OAuth2的实现方式 4、单点登录的技术要点和关键问题 4.1 安全性考虑 4.2 用户体验优化 4.3 高可用性设计 5、Java中的单点登录实

    2024年01月23日
    浏览(46)
  • POM依赖报错解决方案汇总

    POM依赖报错解决方案汇总 状况 1 创建完一个maven项目,在pom文件在引入依赖,等下方自动导入加载完毕,去查看IDEA工具的Maven Projects工具选项中Dependencies 依然后依赖红色报错 2 在pom文件中,引用依赖后,该依赖的版本号处直接出现红色 3 IDEA工具的Maven Projects工具选项中Dependencies下的

    2024年02月08日
    浏览(36)
  • IDEA中maven无法下载依赖解决方案

    如果你尝试了很多网上的办法 仍然没有解决 那么很有可能和我一样碰到**了,解决办法千奇百怪, 解决之前(山丹丹的那个红艳艳)都没我屏幕红,本人试了一下几种 1、检查maven配置 settings.xml(应该都没问题),重建新的仓库(个人不建议这种操作,太麻烦所以我也没试)

    2024年01月20日
    浏览(34)
  • Spring中的循环依赖是什么?如何解决它?

    循环依赖是指两个或多个Bean之间相互依赖,导致它们无法被正确地初始化。在Spring中,当两个或多个Bean之间存在循环依赖时,Spring容器无法决定哪个Bean应该先初始化,因此会抛出BeanCurrentlyInCreationException异常,从而导致应用程序启动失败。   为了解决循环依赖问题,Spr

    2023年04月16日
    浏览(51)
  • JS for循环异步解决方案

    JavaScript中的for循环是一种同步操作,它将阻塞代码的执行,直到循环完成。但是,在处理异步操作时,使用同步for循环会导致问题。 为了解决这个问题,可以使用以下两种异步解决方案: 递归是一种有效的解决方案,它可以确保异步操作按照预期执行。以下是使用递归实现

    2024年02月13日
    浏览(29)

觉得文章有用就打赏一下文章作者

支付宝扫一扫打赏

博客赞助

微信扫一扫打赏

请作者喝杯咖啡吧~博客赞助

支付宝扫一扫领取红包,优惠每天领

二维码1

领取红包

二维码2

领红包