Spring 为什么使用三级缓存解决循环依赖

news2024/10/6 22:30:37

文章目录

    • 前言
      • 1. 什么是循环依赖
        • 1.1 互相依赖
        • 1.2 递归依赖
      • 2. Sping中循环依赖有什么问题?
      • 3. 什么是三级缓存
      • 4. Spring 可以解决哪些情况的循环依赖?
    • 二级缓存作用——普通循环依赖
      • 实操环节
        • 1. 实例化类A对象
        • 2. 实例化类B对象
        • 3. B对象完成创建
        • 4.继续创建A对象
    • 三级缓存作用——aop循环依赖
      • 1. AOP代理问题
      • 2. 何时生成代理对象
      • 实操环节
        • 1.实例化类A对象
        • 2. 实例化类B对象
        • 3.继续创建A对象
    • 结尾




前言

1. 什么是循环依赖

  类A需要类B,我们就叫做类A依赖类B。简单说就是⾃⼰依赖⾃⼰,或者和别的类相互依赖


1.1 互相依赖

1.2 递归依赖

在这里插入图片描述


2. Sping中循环依赖有什么问题?

  在Spring中,循环依赖指的是两个或多个Bean之间相互依赖形成的循环引用关系。具体来说,当Bean A依赖于Bean B,而Bean B又依赖于Bean A时,就形成了循环依赖。

  只有单例的 Bean 才存在循环依赖的情况,原型(Prototype)情况下,Spring 会直接抛出异常。

  循环依赖可能导致以下问题:

  • 无法完成Bean的初始化:当存在循环依赖时,Spring容器无法确定先初始化哪个Bean,因为它们相互依赖,而且都需要对方完成初始化才能继续。这可能导致Bean的初始化过程无法完成,从而引发异常。

  • 无限递归调用:当存在循环依赖时,Spring容器可能会陷入无限递归的调用中,导致系统堆栈溢出。这是因为每次获取Bean时,Spring容器需要检测循环依赖并创建实例,但由于循环依赖的存在,无法正常创建实例,从而导致无限递归调用。

在这里插入图片描述

  为了解决循环依赖问题,Spring使用了三级缓存和"提前暴露"的策略


3. 什么是三级缓存

  对于创建单例Bean,Spring创建了三个容器来存储不同时期的对象:

  1. ⼀级缓存 : Map<String,Object> singletonObjects,单例池,⽤于保存实例化、属性赋值
    (注⼊)、初始化完成的 bean 实例
  2. ⼆级缓存 : Map<String,Object> earlySingletonObjects,早期曝光对象,⽤于保存实例化完
    成的 bean 实例
  3. 三级缓存 : Map<String,ObjectFactory<?>> singletonFactories,早期曝光对象⼯⼚,⽤于
    保存 bean 创建⼯⼚,以便于后⾯扩展有机会创建代理对象
    在这里插入图片描述

4. Spring 可以解决哪些情况的循环依赖?

  Spring 不⽀持基于构造器注⼊的循环依赖,假如 AB 循环依赖,其中一方使用构造器注入,也是不支持的。

在这里插入图片描述

  为什么呢?下面二级缓存会说明白。




二级缓存作用——普通循环依赖

  只用一级缓存和二级缓存就能解决普通bean的循环依赖。
  先回顾Bean对象创建的步骤:
在这里插入图片描述

  二级缓存:又称 半成品池 存放的是实例化,但未属性赋值和初始化的Bean对象。
  一级缓存:又称 单例池 存放的是完成属性赋值和初始化的成品Bean,可以直接使用了。

  那么二级缓存是如何解决普通Bean的循环依赖的?


实操环节

  类A依赖类B,类B依赖类A。

在这里插入图片描述

1. 实例化类A对象

  对象a被实例化出来,会被放到半成品池中,当进行下一步属性赋值时,发现依赖了类B,所以开始创建对象b。
在这里插入图片描述

2. 实例化类B对象

  对象b被实例化出来,也被放到半成品池中。下一步是属性赋值,发现依赖了类A,会依次从⼀级到三级缓存查询类A对象,最终会在半成品池中找到对象a,成功将它赋值到自己的属性中。
在这里插入图片描述

3. B对象完成创建

  对象b在经过填充属性、初始化后会从半成品池里挪到单例池中,可以直接使用了。
在这里插入图片描述

4.继续创建A对象

  这时候回过头来继续对象a的属性注入,把对象b赋值给自己的属性后再经过初始化,对象a也从半成品池挪到单例池,对象a创建完成,对象b也跟着创建完成。
在这里插入图片描述



三级缓存作用——aop循环依赖

  二级缓存仍然存在问题,它无法解决AOP代理问题。

1. AOP代理问题

  AOP(面向切面)简单的说,在不改源码的情况下在原始方法前后加一些代码。
  它的底层是靠动态代理实现的,即生成一个代理类,重新原始方法,真正使用的时候其实用的是代理类对象,而非原始类对象。
  既然用的是代理类对象,单例池中应该存放的就该是代理类对象。
  二级缓存无法解决生成代理对象的问题,因为创建对象的过程很复杂,每个代理类都需要一个工厂来专门生成代理类对象。
在这里插入图片描述

  三级缓存又叫工厂池,就是用来存放生成代理类对象工厂的
在这里插入图片描述

2. 何时生成代理对象

  AOP是靠AOP处理器实现的,处理器有两个生成代理对象的方式。

  • 前置处理:在Bean对象初始化后
  • 后置处理:再Bean对象实例化前
    在这里插入图片描述
      Spring为了解决使用AOP的对象循环依赖的问题,使用了这两种处理方式。

实操环节

  类A依赖类B,类B依赖类A,类A使用了AOP。
在这里插入图片描述

1.实例化类A对象

  首先把创建类A代理对象的工厂对象放到工厂池中。
在这里插入图片描述
  类A实例化对象时发现依赖了类B,使用前置处理器生成A的代理对象,放在半成品池子中。
在这里插入图片描述

2. 实例化类B对象

  对象b找到对象a,成功属性赋值,再经过初始化成功创建,挪到单例池中待用。
  如果类B也使用了AOP,那么对象b在初始化后,会通过后置处理器生成动态代理对象,放到单例池中。
在这里插入图片描述

3.继续创建A对象

  对象b创建完,接着回头创建对象a,这个过程就很顺利了。
  当对象a完成初始化以后,因为已经是代理对象,就不会在走后置处理。
  对象a、b都创建完,会清空在二级、三级池中的相关数据,最终只在单例池中保留一份对象。
在这里插入图片描述




结尾

  尽管Spring提供了解决循环依赖的机制,但循环依赖本身是一个设计上的问题,可能导致代码的可读性和可维护性下降。因此,在编写代码时,应尽量避免出现循环依赖的情况。

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/916304.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

Python自动化小技巧21——实现PDF转word功能(程序制作)

案例背景 为什么这个年代PDF转word&#xff0c;某wps居然还要收费.....很多软件都可以实现这个功能&#xff0c;但是效果都有好有坏&#xff0c;而且有的还付费&#xff0c;很麻烦。 那就用python实现这个功能吧&#xff0c;然后把代码打包为.exe的程序&#xff0c;这样随便在…

SOLIDWORKS提高装配效率的方法:配合参考

SOLIDWORKS装配功能比较强大&#xff0c;但是如果产品中有较多的标准件、企业通用件等&#xff0c;由于这类零件一般量较大&#xff0c;所以装配起来费时费力。同时标准件、企业通用件等相对比较固定&#xff0c;装配方式也相对固定&#xff0c;那有没有办法让SOLIDWORKS自动装…

一文读懂设备管理系统:是什么、谁需要、怎样选

工业的迅猛发展让人类向前迈出了史无前例的步伐&#xff0c;工业4.0将我们又带入了一个信息化技术促进工业变革的新时代——智能化时代。一台台机器设备是工业发展史上必不可少的参与者&#xff0c;但企业对设备的管理存在种种痛点&#xff0c;比如生产设备多&#xff0c;但备件…

ui设计师年终总结精选五篇

2019ui设计师年终总结一 工作一年了&#xff0c;结合我自身谈谈UI设计的重要性。现在主流的论坛建站程序有两种 Phpwind 和Discuz (Phpwind被阿里巴巴收购 Discuz被腾讯收购这两个论坛程序都是开源免费的)&#xff0c;利用这两种程序我都分别建立过论坛&#xff0c;我第一次用…

拼多多app商品详情接口 获取pdd商品主图价格销量库存信息

拼多多是中国一家知名的电商平台&#xff0c;以"社交团购新零售"的商业模式闻名&#xff0c;通过手机app和微信小程序等渠道提供商品销售和购物体验。平台上的商品种类丰富多样&#xff0c;涵盖了服装、家居、美妆、食品、数码电子等各个领域。 拼多多的商业模式主要…

Java 中使用 ES 高级客户端库 RestHighLevelClient 清理百万级规模历史数据

&#x1f389;工作中遇到这样一个需求场景&#xff1a;由于ES数据库中历史数据过多&#xff0c;占用太多的磁盘空间&#xff0c;需要定期地进行清理&#xff0c;在一定程度上可以释放磁盘空间&#xff0c;减轻磁盘空间压力。 &#x1f388;在经过调研之后发现&#xff0c;某服务…

qq windows版客户端0day复现——远程代码执行(七夕小礼物)

##ps&#xff1a;本文章仅用来分享&#xff0c;请勿将文章内的相关技术用于非法目的&#xff0c;请勿将文章内的相关技术用于非法目的&#xff0c;请勿将文章内的相关技术用于非法目的&#xff01;&#xff01;如有非法行为与本文章作者无任何关系。一切行为以遵守《中华人民共…

电力巡检三维数字化管理的新方案:图新地球电力版

电力工业是国民经济发展的重要基础能源产业&#xff0c;是世界各国经济发展战略中的优先发展重点。当前中国电力行业运行平稳&#xff0c;电力消费持续增长&#xff0c;电力装机结构延续绿色低碳发展态势&#xff0c;同时投资规模日益扩大。随着全民用电量持续快速增长&#xf…

从头到尾说一次 Spring 事务管理(器) | 京东云技术团队

事务管理&#xff0c;一个被说烂的也被看烂的话题&#xff0c;还是八股文中的基础股之一。​ 本文会从设计角度&#xff0c;一步步的剖析 Spring 事务管理的设计思路&#xff08;都会设计事务管理器了&#xff0c;还能玩不转&#xff1f;&#xff09; 为什么需要事务管理&…

隐秘的角落:Java连接Oracle提示Connection timed out

前言 这个报错相信各位后端开发都不陌生&#xff0c;大体的原因就那么几种&#xff1a; 检查网络连接&#xff1a;确保您的计算机与数据库服务器之间的网络连接正常。尝试通过其他方式验证您的网络连接是否正常。 检查数据库服务器状态&#xff1a;确保数据库服务器正在运行&…

如何快速了解一家企业的各类信息?

我们在生活和工作会遇到一些情形&#xff0c;需要我们去查找一些企业的信息来推进。这时候如何快速查找到企业的信息呢&#xff1f; 根据场景不同&#xff0c;所需要的企业信息也是不同的&#xff0c;有的可能只需要企业的基本信息&#xff0c;有的情况需要企业的多维度信息&a…

Linux需要掌握哪些?

Linux运维工程师的基本工作之一是搭建相关编程语言的运行环境&#xff0c;使程序能够高效、稳定、安全地在服务器上运行。优秀的Linux运维工程师不但需要拥有架设服务器集群的能力&#xff0c;还需要拥有使用不同的编程语言开发常用的自动化运维工具或平台的能力&#xff0c;从…

SciencePub学术 | 计算机及交叉类重点SCIE征稿中

SciencePub学术 刊源推荐: 计算机及交叉类重点SCIE征稿中&#xff01;信息如下&#xff0c;录满为止&#xff1a; 一、期刊概况&#xff1a; 计算机土地类重点SCIE 【期刊简介】IF&#xff1a;1.0-1.5&#xff0c;JCR4区&#xff0c;中科院4区&#xff1b; 【版面类型】正刊…

LTDC之存储器映射闪存

对于大多数项目&#xff0c;建议使用外部闪存&#xff0c;因为这允许应用程序使用多个大型图像。 即便最普通的应用程序&#xff0c;内部闪存也可能会很快被占用完。 1.配置QSPI&#xff08;嵌入式基础知识&#xff0c;此处不做分析&#xff09; 2.编写W25Q256配置代码&#xf…

django+MySQL购物商城系统(含源码+论文)

对购物商城管理的流程进行科学整理、归纳和功能的精简&#xff0c;通过软件工程的研究方法&#xff0c;结合当下流行的互联网技术&#xff0c;最终设计并实现了一个简单、易操作的购物商城系统。内容包括系统的设计思路、系统模块和实现方法。系统使用过程主要涉及到管理员和用…

[JavaWeb]【九】web后端开发-SpringBootWeb案例(菜单)

目录 一、准备工作 1.1 需求 1.2 环境搭建 1.2.1 准备数据库&表 1.2.2 创建springboot工程 1.2.3 配置application.properties & 准备对应实体类 1.2.3.1 application.properties 1.2.3.2 实体类 1.2.3.2.1 Emp类 1.2.3.2.2 Dept类 1.2.4 准备对应的Mapper、…

[C#][原创]操作注册表一些注意点

C#注册表只需要引入 using Microsoft.Win32; C#注册表操作都是通过2个类Registry和RegistryKey进行所有操作。但是有些基本注意事项经常忘记&#xff0c;不常用就很容易忘记。 第一&#xff0c;打开注册表&#xff0c;第2个bool参数问题&#xff1a; RegistryKey key Regi…

算法与数据结构(九)--并查集

并查集是一种树型的数据结构&#xff0c;并查集可以高校地进行如下操作&#xff1a; *查询元素p和元素q是否在同一组 *合并元素p和元素q所在的组 一.并查集结构 并查集也是一种树型结构&#xff0c;这种树的要求比较简单&#xff1a;1.每个元素都唯一的对应一个结点&#xff…

海外ios应用商店优化排名因素之关键词

与Google Play Store相比&#xff0c;在Apple的App Store中&#xff0c;应用描述不会影响关键词排名。不过有一个专门针对App Store的关键词列表&#xff0c;我们可以在其中放置相关关键词。 1、关键词列表的限制仅为100个字符。 使用排名的竞争性较低的关键词&#xff0c;尝试…

Ubuntu无法连接外网

配置环境时&#xff0c;发现实验室服务器这阵子不能连接外网&#xff0c;网上看看了解决方案&#xff0c;确定是DNS的问题&#xff0c;解决方案如下&#xff1a; 首先&#xff0c;我尝试ping www.baidu.com,是可以ping通的&#xff0c;内网访问没问题。排除是否为网络连接问题…