Spring 循环依赖会出现什么情况? 如何解决?

news2024/10/5 0:13:29

Spring 循环依赖会出现什么情况? 如何解决?

一、什么是循环依赖?

在Spring项目中我们经常使用 @Autowired或者@Resource去注入Bean,我们称之为依赖。
当多个Bean之间存在互相依赖的关系,并且出现了循环调用时,Spring就会找不到依赖的七点,就会死循环直到抛出异常。
例如:A依赖B,B依赖C,C依赖A,三者必须在依赖的类初始化之后才会初始化自己,从而出现死循环。

二、实战场景

笔者是在使用Spring Security 编写登录和权限验证代码时出现了循环依赖的场景。

三、解决方法

省流: 笔者使用的方法

  1. 使用@Lazy延迟创建对象
  2. 将@Resource替换为@Autowired
  3. 新建一个空Bean,来解决依赖问题: 例如 A依赖B,B依赖A,我们可以新建一个C,然后让A依赖C,B实现C即可将直接依赖转化为间接依赖关系 中介方式打破循环链
     
    public interface C {
        void doSomething();
    }
    
    
    public class B implements C {
        @Override
        public void doSomething() {
            
        }
    }
    
    
    public class A {
        private C c;
    
        public A(C c) {
            this.c = c;
        }
    
        public void doSomething() {
            c.doSomething();
        }
    }

四、扩展:@Autowired是如何解决循环依赖的的问题的

解决的核心是使用了Spring的三级缓存:

  • 第一级缓存:singletonObjects,用于存放完全初始化好的bean,避免重复创建,单例池
  • 二级缓存:earlySingletonObjects 存放原始的bean对象,尚未填充属性,同时也没有进行完成依赖注入的类 (核心)
  • 三级缓存:singletonFactories 用于存放bean工厂对象中的getObject方法,用于产生原始的bean或者代理对象(如果Bean被AOP切面代理)来放入二级缓存
    首先我们要知道,实例化 ≠ 完全初始化,当Spring容器创建bean时,会从一级缓存中寻找,如果没找到,会搜索二级缓存,如果存在就会把它注入,如果没有会找三级缓存。当bean初始化时,如果发现依赖的类没有完成完全初始化,就会先使用二级缓存中的bean实例,当所有的bean都初始化之后再从一级缓存中获取完全初始化的bean
    而我们使用的@Resource并不存在这种机制,会直接抛出BeanCurrentlyInCreationException
    只用两级缓存可以吗?
    如果没有AOP的情况下只是用一级和三级缓存就能解决,但是涉及到AOP时,必须使用了
    如果发生循环依赖的话,就去 三级缓存 singletonFactories 中拿到三级缓存中存储的 ObjectFactory 并调用它的 getObject() 方法来获取这个循环依赖对象的前期暴露对象(虽然还没初始化完成,但是可以拿到该对象在堆中的存储地址了),并且将这个前期暴露对象放到二级缓存中,这样在循环依赖时,就不会重复初始化了!

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

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

相关文章

【AI学习】Mamba学习(二):线性注意力

上一篇《Mamba学习(一):总体架构》提到,Transformer 模型的主要缺点是:自注意力机制的计算量会随着上下文长度的增加呈平方级增长。所以,许多次二次时间架构(指一个函数或算法的增长速度小于二次…

C++ 多态:重塑编程效率与灵活性

目录 多态的概念 多态的定义及实现 多态的构成条件 虚函数 虚函数的重写 虚函数重写的两个例外: 1. 协变(基类与派生类虚函数返回值类型不同) 2. 析构函数的重写(基类与派生类析构函数的名字不同) 析构函数要不要定义成虚函数?&…

绝对值得收藏!分享7款ai写作论文免费一键生成网站

在当前的学术研究和写作过程中,AI写作工具已经成为了许多研究者和学生的重要助手。这些工具不仅能够提高写作效率,还能帮助生成高质量的论文内容。以下是七款免费的AI写作论文生成器,其中特别推荐千笔-AIPassPaper。 1.千笔-AIPassPaper 千…

信号处理: Block Pending Handler 与 SIGKILL/SIGSTOP 实验

1. 信号处理机制的 “三张表” kill -l :前 31 个信号为系统标准信号。 block pending handler 三张表保存在每个进程的进程控制块 —— pcb 中,它们分别对应了某一信号的阻塞状态、待处理状态以及处理方式。 block :通过 sigset_t 类型实现&…

YOLO11改进 | 检测头 | 融合渐进特征金字塔的检测头【AFPN3】

秋招面试专栏推荐 :深度学习算法工程师面试问题总结【百面算法工程师】——点击即可跳转 💡💡💡本专栏所有程序均经过测试,可成功执行💡💡💡 本文介绍了一个渐进特征金字塔网络&…

关于 S7 - 1200 通过存储卡进行程序更新

西门子S7-1200系列PLC可以通过存储卡进行程序的更新,固件版本的升级以及程序数据的存储多项功能。本例进行程序更新的操作。 存储卡的订货号以及存储容量 一;如何插入存储卡 在CPU断电下,将CPU上挡板向下掀开,可以看到右上角有一…

ai写作论文会被检测吗?分享市面上7款自动写论文网站

近年来,随着人工智能技术的飞速发展,AI写作工具在学术界引起了广泛关注。然而,这些工具的使用也引发了关于学术诚信和检测机制的讨论。根据多所高校的声明,为了应对AI代写论文的现象,许多高校已经开始引入论文检测工具…

Python入门:深入了解__init__.py 文件(如何实现动态导入子模块)

文章目录 📖 介绍 📖🏡 演示环境 🏡📒 文章内容 📒📝 `__init__.py` 的作用示例:📝 如何编写 `__init__.py`1. 空的 `__init__.py`2. 导入子模块3. 初始化代码4. 动态导入子模块📝 编写 `__init__.py` 的技巧和注意事项⚓️ 相关链接 ⚓️📖 介绍 📖 在…

01:(寄存器开发)点亮一个LED灯

寄存器开发 1、单片机的简介1.1、什么是单片机1.2、F1系列内核和芯片的系统架构1.3、存储器映像1.4、什么是寄存器 2、寄存器开发模板工程3、使用寄存器点亮一个LED4、代码改进15、代码改进2 本教程使用的是STM32F103C8T6最小系统板,教程来源B站up“嵌入式那些事”。…

前缀和(6)_和可被k整除的子数组_蓝桥杯

个人主页:C忠实粉丝 欢迎 点赞👍 收藏✨ 留言✉ 加关注💓本文由 C忠实粉丝 原创 前缀和(6)_和可被k整除的子数组 收录于专栏【经典算法练习】 本专栏旨在分享学习算法的一点学习笔记,欢迎大家在评论区交流讨论💌 目录 …

kubeadm部署k8s

1.1 安装Docker [rootk8s-all ~]# wget -O /etc/yum.repos.d/docker-ce.repo https://mirrors.huaweicloud.com/docker-ce/linux/centos/docker-ce.repo [rootk8s-all ~]# sed -i sdownload.docker.commirrors.huaweicloud.com/docker-ce /etc/yum.repos.d/docker-ce.repo [ro…

基于Keras的U-Net模型在图像分割与计数中的应用

关于深度实战社区 我们是一个深度学习领域的独立工作室。团队成员有:中科大硕士、纽约大学硕士、浙江大学硕士、华东理工博士等,曾在腾讯、百度、德勤等担任算法工程师/产品经理。全网20多万粉丝,拥有2篇国家级人工智能发明专利。 社区特色&a…

Yocto - 使用Yocto开发嵌入式Linux系统_07 构建使用的临时文件夹

Detailing the Temporary Build Directory 在本章中,我们将尝试了解映像生成后临时构建目录的内容,并了解 BitBake 如何在烘焙过程中使用它。此外,我们还将了解这些目录中的某些内容如何在出现问题时作为有价值的信息来源来帮助我们。 In thi…

前缀和——从LeetCode题海中总结常见套路

目录 前缀和定义 截断前缀和DP:LeetCode53.最大子序和 经典左右指针:LeetCode209.长度最小的子数组 暴力求解:超时 优雅的双指针写法一: 优雅的双指针写法二: LeetCode.1588.所有奇数长度子数组的和 手速题&am…

springboot系列--web相关知识探索三

一、前言 web相关知识探索二中研究了请求是如何映射到具体接口(方法)中的,本次文章主要研究请求中所带的参数是如何映射到接口参数中的,也即请求参数如何与接口参数绑定。主要有四种、分别是注解方式、Servlet API方式、复杂参数、…

[大语言模型-算法优化] 微调技术-LoRA算法原理及优化应用详解

[大语言模型-算法优化] 微调技术-LoRA算法原理及优化应用详解 前言: 古人云: 得卧龙者,得天下。 然在当今大语言模型流行的时代,同样有一句普世之言: 会微调技术者,得私域大模型部署之道! 在众多微调技术中,LoRA (…

单细胞scDist细胞扰动差异分析学习

scDist通过分析不同状态下细胞的距离来找到差异最大的细胞亚群(见下图的A),然后再分析每一个细胞亚群的PCA通过线性的混合模型并结合最终的系数去预估不同干预方式下细胞群之间的距离。 Augur是通过对每一个细胞进行AUC评分并排序最终找到扰动最佳的细胞群&#xf…

等额本金和等额本息是什么意思?

等额本金和等额本息是两种常见的贷款还款方式,它们各自有着不同的特点和适用场景。下面我将用通俗易懂的语言来解释这两种还款方式: 等额本金 定义:等额本金指的是在贷款期限内,每月偿还相同数额的本金,而利息则随着剩…

FPGA远程烧录bit流

FPGA远程烧录bit流 Vivado支持远程编译并下载bit流到本地xilinx开发板。具体操作就是在连接JTAG的远程电脑上安装hw_server.exe。比如硬件板在实验室或者是其他地方,开发代码与工程在本地计算机,如何将bit流烧录到实验室或者远程开发板? vi…

Socket套接字(客户端,服务端)和IO多路复用

Socket套接字(客户端,服务端) 目录 socket是什么一、在客户端1. 创建套接字2. 设置服务器地址3. 连接到服务器4. 发送数据5. 接收数据6. 关闭连接 二、内核态与用户态切换三、系统调用与上下文切换的关系四、在服务端1. 创建 Socket (用户态…