Spring中的循环依赖问题

目录

1、什么是Spring的循环依赖?

2、如何避免循环依赖问题?

3、Spring的三级缓存

小结


1、什么是Spring的循环依赖?

Spring框架中的循环依赖问题是指两个或多个bean之间相互依赖,形成闭环,导致无法完成实例化的问题。简单来说,就是A依赖于B,而B又依赖于A,形成了一个循环的依赖链。

循环依赖问题可能导致应用程序启动失败或者产生不可预期的行为。这是因为当Spring容器创建Bean时,会使用默认的构造函数或Setter方法将依赖注入到Bean中。如果存在循环依赖,那么容器无法确定先创建哪个Bean,从而导致无法完成依赖注入。

⭐扩展:Bean的创建过程:

图片来源:深谈Spring如何解决Bean的循环依赖

在Spring中,循环依赖主要分为两种类型:构造器的循环依赖和field属性的循环依赖。

2、如何避免循环依赖问题?

首先需要明确的一点是,Spring 并不能解决所有循环依赖的问题。Spring提供了以下几种解决循环依赖问题的方式:

1. 构造器注入:Spring容器在创建bean时,会先创建所有没有依赖关系的bean,然后再创建有依赖关系的bean。在创建有依赖关系的bean时,Spring会先创建构造器参数中所需要的bean,然后再创建当前bean。使用构造函数注入代替Setter方法注入,可以确保在创建Bean时所有的依赖都已经提供,这种方式可以解决大部分的循环依赖问题。

2. 使用setter方法注入依赖:在这种情况下,Spring容器可以在实例化bean后通过调用setter方法来注入所需的依赖。

3. 使用@Lazy注解:@Lazy注解可以延迟加载bean的实例化。通过将Bean设置为延迟加载,当需要使用该bean时才会进行实例化。这种方式可以解决部分的循环依赖问题。

4. 使用@Autowired注解搭配@Qualifier注解明确指定依赖关系。通过使用@Qualifier注解,可以明确指定依赖的Bean名称,从而帮助Spring容器正确解析循环依赖。

5. 使用@PostConstruct注解和InitializingBean接口。这两种方式可以在Bean创建完成后执行特定的初始化操作,可以在初始化方法中处理循环依赖的情况。

6. 使用代理:在这种情况下,可以使用AOP代理来实现bean之间的依赖关系。这样,就可以在编译时就解决循环依赖问题。

图片来源:https://www.cnblogs.com/mghio/p/15024461.html

3、Spring的三级缓存

在Spring中,Bean的创建过程中涉及到三级缓存(三级缓存是在Spring 4.x之前的版本中使用的机制):

  1. singletonObjects:这是一级缓存,用于存储完全初始化并准备好的单例Bean实例。这些Bean实例是最终被返回的单例Bean实例。在缓存中,Bean的名字和Bean实例是以键值对的形式存在的。当Bean的依赖注入完成并且初始化后,它会被放置在这个缓存中。

  2. earlySingletonObjects:这是二级缓存,用于存放已经创建,但还未完成初始化的单例Bean实例。这些Bean实例通常是因为依赖其他Bean实例而无法完成初始化,处于不完整状态。在Bean的初始化过程中,如果发现循环依赖,则会将尚未完全初始化的Bean放置在这个缓存中,以便解决循环依赖问题。

  3. singletonFactories:这是三级缓存,用于存储用于创建单例Bean的ObjectFactory工厂对象,这些工厂对象可以用来创建单例Bean实例。当Spring正在创建一个Bean时,如果发现了循环依赖,则会将该Bean的创建工厂放置在这个缓存中,在需要时可以通过该工厂来获取Bean的实例。

图片来源:Spring 的循环依赖问题 - mghio - 博客园

当两个相互依赖的Bean需要被实例化时,Spring会先查看第一级缓存中是否已经有完整的Bean实例。如果有,就使用已有的实例;如果没有,则进入第二级缓存查看是否有已经创建但未初始化的Bean实例。如果有,就使用这个未初始化的Bean实例去初始化另一个Bean,然后再将这个未初始化的Bean实例存入第一级缓存;如果没有,则进入第三级缓存查看是否有可以用来创建Bean实例的工厂对象。如果有,就使用这个工厂对象去创建Bean实例,然后再将这个新创建的Bean实例存入第一级缓存;如果没有,则直接创建新的Bean实例存入第一级缓存。

通过三级缓存机制,Spring可以在循环依赖的情况下正确地初始化每个Bean,避免了出现错误或异常。同时,三级缓存也有效地减少了不必要的重复初始化操作,提高了应用程序的性能。

这三级缓存的使用可以帮助Spring容器在处理循环依赖时能够正确地获取到Bean的实例,并最终完成整个Bean的创建和初始化过程。在Spring 5.x及更新的版本中,已经不再使用三级缓存,而是采用了更加高效和可靠的解决方案来处理循环依赖的问题。

小结

需要注意的是,尽管Spring提供了一些机制来解决循环依赖问题,但是最好的做法仍然是尽量减少组件之间的相互依赖,尽量保持低耦合的设计,从而避免出现循环依赖的情况。良好的设计和架构能够减少循环依赖的发生,提高应用程序的可维护性和可测试性。

参考:

Spring 的循环依赖问题 - mghio - 博客园

深谈Spring如何解决Bean的循环依赖

今天一定要搞清楚Spring如何解决循环依赖

Spring 循环依赖解决方案_spring解决循环依赖-CSDN博客


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

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈qq邮箱809451989@qq.com,一经查实,立即删除!

相关文章

儿童绘本故事:鱼小乐的海洋奇幻之旅

《鱼小乐的海洋奇幻之旅》Chapter 1: 美好的计划一个晴朗的日子,鱼小乐和她的同学们聚在一起,兴奋地计划着一场奇妙的冒险。他们决定一起前往珠海海洋王国,展开一场海洋奇幻之旅。On a sunny day, Fishy Joy and her classmates gathered tog…

JDBC编程基础

JDBC编程基础 JDBC介绍创建JDBC项目的步骤1.引入依赖2.注册驱动3.获取数据库连接4.获取sql执行对象 JDBC 常用 API 详解sql执行对象PreparedStatement作用 事务管理结果集对象 JDBC项目demo测试 JDBC介绍 每个数据库都会提供一组API来支持程序员实现自己客户端,自己…

文心一言 VS 讯飞星火 VS chatgpt (145)-- 算法导论12.1 5题

五、用go语言,因为在基于比较的排序模型中,完成n个元素的排序,其最坏情况下需要 Ω(nlgn) 时间。试证明:任何基于比较的算法从 n 个元素的任意序列中构造一棵二又搜索树,其最坏情况下需要 Ω(nlgn) 的时间。 我个人喜欢 灵小智 。…

Java 简易版王者荣耀

所有包和类 GameFrame类 package newKingOfHonor;import java.awt.*; import java.awt.event.ActionEvent; import java.awt.event.ActionListener; import java.awt.event.KeyAdapter; import java.awt.event.KeyEvent; import java.io.File; import java.util.ArrayList;im…

初刷leetcode题目(9)——数据结构与算法

😶‍🌫️😶‍🌫️😶‍🌫️😶‍🌫️Take your time ! 😶‍🌫️😶‍🌫️😶‍🌫️😶‍🌫️…

封装可多选的组件(Autocomplete)

一。组件库Material UI 1.1 地址 https://v4.mui.com/zh/getting-started/installation/ 1.2 简介 自称世界上最受欢迎的React UI组件库(能看到这里的基本用法应该都清楚了,我就不重复了) 二。效果展示 三。代码展示 import React from reactimport { useField, us…

sql中group by和having的使用

group by:按照某个字段或者某些字段进行分组。 having:对分组之后的数据进行再次过滤,having必须和group by一起用,且在group by后面。 比如person表如下(以下查询均基于此表): 1.group by 用法…

linux 命令 sudo、su 命令

sudo命令详解 1、初识sudo sudo是linux下常用的允许普通用户使用超级用户权限的工具,sudo 用来执行需要提升权限(通常是作为 root 用户)的命令,允许系统管理员让普通用户执行一些或者全部的root命令,如halt&#xff…

002、ArkTS

之——开发语言 目录 之——开发语言 杂谈 正文 1.TypeScript基础 1.1 基础类型 1.2 条件语句 1.3 函数 1.4 类 1.5 模块 1.6 迭代器 2.ArkTS 2.1 JAVA SCRIPT 2.2 TS 2.3 ArkTS ​编辑 3.示例 3.1 概述性示例 3.2 自定义组件 3.3 渲染控制语法 3.4 状态管…

【C++】什么是模板?怎样使用模板?

👀樊梓慕:个人主页 🎥个人专栏:《C语言》《数据结构》《蓝桥杯试题》《LeetCode刷题笔记》《实训项目》《C》 🌝每一个不曾起舞的日子,都是对生命的辜负 目录 前言 1.函数模板 1.1函数模板概念 1.2函数…

研究前沿|NAR:一个综合性的植物代谢组数据库

引言 2023年10月,华中农业大学小麦改良创新团队陈伟教授课题组在Nucleic Acids Research发表题为“PMhub 1.0: a comprehensive plant metabolome database”的文章,系统介绍了他们开发的植物代谢分析网站(PMhub)的功能与价值。P…

Maven生命周期

Maven生命周期 通过IDEA工具的辅助,能很轻易看见Maven的九种生命周期命令,如下: 双击其中任何一个,都会执行相应的Maven构建动作,为啥IDEA能实现这个功能呢?道理很简单,因为IDEA封装了Maven提供…

PDF控件Spire.PDF for .NET【转换】演示:将C#/VB.NET:将 PDF 转换为 PostScript (PS)

PostScript 是 Adobe Systems 在 20 世纪 80 年代开发的一种将数字图形或文本文件转换为可供打印的固定格式的方法。随着时间的推移,虽然 PostScript (PS) 文件格式不再像以前那样流行,但现在大多数打印机仍然支持它。在本文中,您将了解如何使…

【刷题笔记】匹配字符串||KMP||动图解析||符合思维方式

找出字符串中第一个匹配项的下标 1 题目描述 https://leetcode.cn/problems/find-the-index-of-the-first-occurrence-in-a-string/ 给你两个字符串 haystack 和 needle ,请你在 haystack 字符串中找出 needle 字符串的第一个匹配项的下标(下标从 0 开…

IP-Adapter:文本兼容图像提示适配器,用于文本到图像扩散模型

IP-Adapter这是一种有效且轻量级的适配器,用于实现预训练文本到图像扩散模型的图像提示功能。只有 22M 参数的 IP 适配器可以实现与微调图像提示模型相当甚至更好的性能。IP-Adapter 不仅可以推广到从同一基本模型微调的其他自定义模型,还可以推广到使用…

OpenVINO异步Stable Diffusion推理优化方案

文章目录 Stable Diffusion 推理优化背景技术讲解:异步优化方案思路:异步推理优化原理OpenVINO异步推理Python API同步和异步实现方式对比 oneflow分布式调度优化优势:实现思路 总结: Stable Diffusion 推理优化 背景 2022年&am…

Selenium 连接到现有的 Firefox 示例

当前环境: python 3.7 selenium 3.14.1 urllib3 1.26.8 Frefox 115.1.0esr(32位) geckodriver.exe 0.33.0 1 下载 Firefox 浏览器,根据自己的需要选择。 下载 Firefox 浏览器,这里有简体中文及其他 90 多种语言版本…

招标采购软件如何让采购变得更轻松?

企业总是希望让采购流程更简单,选择更好的供应商,花更少的钱。采购软件的普及使原材料和服务的采购变得更容易,向供应商(甚至是全球供应商)索取信息的流程已大大简化。包括招标采购软件在内的采购技术已成为企业运营不…

Elasticsearch(ES)概述

文章目录 一.什么是Elasticsearch?1.正向索引和倒排索引2.Mysql和ES的概念对比3.安装elasticsearch、kibana 二.IK分词器三.索引库操作四.文档操作五.RestClient操作索引库1.初始化RestClient2.创建索引库3.删除索引库4.判断索引库是否存在 六.RestClient操作文档1.新增文档2.…

【开发实践】使用POI实现导出带有复杂表头的的excel文件

一、需求分析 公司业务部门需要&#xff0c;根据一些数据&#xff0c;加上表头&#xff0c;导出需要的excel表格。效果如下&#xff1a; 二、代码实现 【依赖准备】 <!-- POI --><dependency><groupId>org.apache.poi</groupId><artifactId>po…