当前位置:首页 > 科技  > 软件

一篇带给你 Spring 循环依赖详解

来源: 责编: 时间:2024-04-15 18:15:26 311观看
导读Spring 循环依赖解决办法及使用案例在 Spring 中,循环依赖指的是两个或多个 Bean 之间相互依赖,形成了一个循环引用的关系。这种情况下,Spring 容器无法完成正确的依赖注入,可能导致应用程序无法启动或出现错误。下面是一

gjE28资讯网——每日最新资讯28at.com

Spring 循环依赖解决办法及使用案例

在 Spring 中,循环依赖指的是两个或多个 Bean 之间相互依赖,形成了一个循环引用的关系。这种情况下,Spring 容器无法完成正确的依赖注入,可能导致应用程序无法启动或出现错误。gjE28资讯网——每日最新资讯28at.com

下面是一种循环依赖的示例及解决办法:gjE28资讯网——每日最新资讯28at.com

示例: 假设有两个类 A 和 B,它们相互依赖。gjE28资讯网——每日最新资讯28at.com

public class A {    private B b;    public A(B b) {        this.b = b;    }}public class B {    private A a;    public B(A a) {        this.a = a;    }}

在上述示例中,类 A 依赖于类 B,而类 B 依赖于类 A,形成了循环依赖。gjE28资讯网——每日最新资讯28at.com

解决办法:gjE28资讯网——每日最新资讯28at.com

构造函数注入改为 Setter 注入:将循环依赖的类的构造函数注入方式改为 Setter 注入。这样,在创建 Bean 实例后,先设置依赖的 Bean,再通过 Setter 方法注入依赖。gjE28资讯网——每日最新资讯28at.com

public class A {    private B b;    public void setB(B b) {        this.b = b;    }}public class B {    private A a;    public void setA(A a) {        this.a = a;    }}

使用 @Lazy 注解:在循环依赖的其中一个类上使用 @Lazy 注解。这样,在初始化 Bean 时,Spring 会创建一个代理对象来解决循环依赖。gjE28资讯网——每日最新资讯28at.com

@Componentpublic class A {    private B b;    public A(@Lazy B b) {        this.b = b;    }}@Componentpublic class B {    private A a;    public B(A a) {        this.a = a;    }}

在上述示例中,类 A 使用了 @Lazy 注解,告诉 Spring 在初始化时暂时不解决依赖,而是创建一个代理对象。这样,当类 B 注入 A 时,实际上会注入 A 的代理对象,从而解决循环依赖。gjE28资讯网——每日最新资讯28at.com

请注意,循环依赖是一种设计上的问题,应尽量避免出现。在实际开发中,应优化类之间的依赖关系,减少循环引用的发生。如果确实遇到循环依赖,可以考虑上述解决办法来解决问题。gjE28资讯网——每日最新资讯28at.com

Spring 是如何解决循环依赖的呢

Spring 使用了三级缓存来解决循环依赖的问题。下面是 Spring 解决循环依赖的基本过程:gjE28资讯网——每日最新资讯28at.com

  • 创建对象:当 Spring 容器创建一个 Bean 时,会先创建一个空的对象实例,并将其放入一级缓存中。
  • 注入属性:Spring 会为该对象注入依赖的属性。如果发现有循环依赖,Spring 会将当前对象提前暴露给容器,但属性值仍然是空的。
  • 提前暴露对象:Spring 将未完成依赖注入的对象放入二级缓存中,以便后续使用。
  • 注入剩余属性:Spring 继续为对象注入剩余的属性。如果发现依赖的属性需要循环依赖的对象,Spring 会从二级缓存中获取暴露的对象,完成依赖注入。
  • 完成对象创建:当所有依赖注入完成后,Spring 将对象放入三级缓存中,并执行初始化操作。
  • 解决循环依赖:当其他 Bean 需要循环依赖的对象时,Spring 会从三级缓存中获取已创建的对象,而不是再次创建新的对象。

通过使用三级缓存,Spring 实现了在循环依赖情况下的对象创建和依赖注入。它通过提前暴露半成品对象,并从缓存中获取已创建的对象来解决循环依赖的问题。gjE28资讯网——每日最新资讯28at.com

需要注意的是,Spring 的循环依赖解决仅适用于单例作用域的 Bean,默认情况下,原型作用域的 Bean 不会解决循环依赖。如果出现原型作用域的循环依赖,Spring 会抛出异常并拒绝创建。gjE28资讯网——每日最新资讯28at.com

Spring 为何要三级缓存 二级缓存已经可以解决循环依赖了啊

对于 Spring 解决循环依赖的过程中,为什么需要三级缓存而不仅仅使用二级缓存的问题,可以从以下几个方面来解释:gjE28资讯网——每日最新资讯28at.com

  • 提前暴露对象:当发现循环依赖时,Spring 需要将当前对象提前暴露给容器,以满足其他 Bean 对它的依赖。二级缓存中的对象仍然处于未完成状态,无法满足其他 Bean 的依赖关系。通过在一级缓存中创建对象实例,提前暴露对象,可以解决这个问题。
  • 避免重复创建对象:二级缓存只能存储未完成的对象实例,而无法存储已经完成依赖注入的对象。如果只使用二级缓存,在依赖注入过程中,每次都需要重新创建对象实例,增加了重复工作的开销。而通过三级缓存,已经完成依赖注入的对象可以被缓存起来,以供后续使用,避免了重复创建对象的操作。
  • 支持循环依赖链的解决:在复杂的应用中,可能存在多个 Bean 之间形成的循环依赖链。二级缓存只能存储当前对象及其直接依赖,无法处理链式依赖关系。而通过三级缓存,可以将整个循环依赖链中的对象都缓存起来,并在需要时进行获取和注入。

综上所述,使用三级缓存的目的是为了提前暴露对象、避免重复创建对象以及支持复杂的循环依赖链的解决。通过三级缓存,Spring 能够更有效地管理和解决循环依赖的问题,确保对象的正确创建和依赖注入。gjE28资讯网——每日最新资讯28at.com

本文链接:http://www.28at.com/showinfo-26-83629-0.html一篇带给你 Spring 循环依赖详解

声明:本网页内容旨在传播知识,若有侵权等问题请及时与本网联系,我们将在第一时间删除处理。邮件:2376512515@qq.com

上一篇: 81道SSM经典面试题总结

下一篇: 掌握Hatch,轻松管理Python包的依赖关系和发布流程!

标签:
  • 热门焦点
  • K60至尊版刚预热 一加Ace2 Pro正面硬刚

    Redmi这边刚如火如荼的宣传了K60 Ultra的各种技术和硬件配置,作为竞品的一加也坐不住了。一加中国区总裁李杰发布了两条微博,表示在自家的一加Ace2上早就已经采用了和PixelWo
  • 5月安卓手机好评榜:魅族20 Pro夺冠

    性能榜和性价比榜之后,我们来看最后的安卓手机好评榜,数据来源安兔兔评测,收集时间2023年5月1日至5月31日,仅限国内市场。第一名:魅族20 Pro好评率:97.50%不得不感慨魅族老品牌还
  • 分享六款相见恨晚的PPT模版网站, 祝你做出精美的PPT!

    1、OfficePLUSOfficePLUS网站旨在为全球Office用户提供丰富的高品质原创PPT模板、实用文档、数据图表及个性化定制服务。优点:OfficePLUS是微软官方网站,囊括PPT模板、Word模
  • 只需五步,使用start.spring.io快速入门Spring编程

    步骤1打开https://start.spring.io/,按照屏幕截图中的内容创建项目,添加 Spring Web 依赖项,并单击“生成”按钮下载 .zip 文件,为下一步做准备。请在进入步骤2之前进行解压。图
  • .NET 程序的 GDI 句柄泄露的再反思

    一、背景1. 讲故事上个月我写过一篇 如何洞察 C# 程序的 GDI 句柄泄露 文章,当时用的是 GDIView + WinDbg 把问题搞定,前者用来定位泄露资源,后者用来定位泄露代码,后面有朋友反
  • 一文搞定Java NIO,以及各种奇葩流

    大家好,我是哪吒。很多朋友问我,如何才能学好IO流,对各种流的概念,云里雾里的,不求甚解。用到的时候,现百度,功能虽然实现了,但是为什么用这个?不知道。更别说效率问题了~下次再遇到,
  • 拼多多APP上线本地生活入口,群雄逐鹿万亿市场

    Tech星球(微信ID:tech618)文 | 陈桥辉 Tech星球独家获悉,拼多多在其APP内上线了“本地生活”入口,位置较深,位于首页的“充值中心”内,目前主要售卖美食相关的
  • 消费结构调整丨巨头低价博弈,拼多多还卷得动吗?

    来源:征探财经作者:陈香羽随着流量红利的退潮,电商的存量博弈越来越明显。曾经主攻中高端与品质的淘宝天猫、京东重拾“低价”口号。而过去与他们错位竞争的拼多多,靠
  • 2纳米决战2025

    集微网报道 从三强争霸到四雄逐鹿,2nm的厮杀声已然隐约传来。无论是老牌劲旅台积电、三星,还是誓言重回先进制程领先地位的英特尔,甚至初成立不久的新
Top