Spring使用 * 缓存解决循环依赖的问题
作者:编程の小白 发布时间:2023-03-14 09:06:15
Spring如何使用 * 缓存解决循环依赖在没开始文章之前首先来了解一下什么是循环依赖
@Component
public class A {
@Autowired
B b;
}
@Component
public class B {
@Autowired
A a;
}
在对象A创建过程中,需要注入B,因为容器中没有B,则去创建B,B创建过程中又需要注入A,而A在等待B的创建,B在等待A的创建,导致两者都无法创建成功,无法加入到单例池供用户使用。
Spring则通过 * 缓存来解决循环依赖的问题,另外如果对象的作用范围是Prototype,则无法通过 * 缓存解决循环依赖,会抛出BeanCurrentlyInCreationException
异常,构造注入的方式,也无法解决循环依赖,只有set注入可以解决。
那么 * 缓存又是什么呢?
* 缓存就是三个Map
public class DefaultSingletonBeanRegistry extends SimpleAliasRegistry implements SingletonBeanRegistry {
//一级缓存(单例池,经过完成生命周期的对象会放入其中)
private final Map<String, Object> singletonObjects = new ConcurrentHashMap<>(256);
//二级缓存(刚实例化还未初始化的原始对象会放入其中)
private final Map<String, Object> earlySingletonObjects = new HashMap<>(16);
// * 缓存(存放创建某个对象的工厂)
private final Map<String, ObjectFactory<?>> singletonFactories = new HashMap<>(16);
Spring Bean对象从创建到初始化大致会经过四个流程
getSingleton()
、doCreateBean()
、populateBean()
、addSingleton()
getSingleton
:从单例池中获取bean对象,如果没有,则进行创建doCreateBean()
:创建bean对象populateBean()
:填充依赖,如果被填充的对象不存在于单例池,则进行创建等四个流程addSingleton()
:将初始化完成的对象加入到单例池
循环依赖的对象在 * 缓存中的迁移过程
A 创建过程中需要 B, 于是 A 将自己放到 * 缓存里面,去实例化 B
B 实例化的时候发现需要 A,于是 B 先查一级缓存,没有,再查二级缓存,还是没有,再查 * 缓存
找到了A,然后把 * 缓存中的 A 放到二级缓存,并删除 * 缓存中的 A
B 顺利初始化完毕,将自己放到一级缓存中(此时 B 中的 A 还是创建中状态,并没有完全初始化),删除 * 缓存中的 B
然后接着回来创建 A,此时 B 已经完成创建,直接从一级缓存中拿到 B,完成 A 的创建,并将 A 添加到单例池,删除二级缓存中的 A
图示:
来源:https://www.cnblogs.com/fkPrograming/p/14873803.html


猜你喜欢
- 写了一个可以扫描附近蓝牙设备的小Demo,可以查看蓝牙设备的设备名和Mac地址代码量不多,很容易看懂/** * 作者:叶应是叶 * 时间:2
- 本文实例为大家分享了C# Winform实现圆角无锯齿按钮的具体代码,供大家参考,具体内容如下发现用Winform做一个圆角按钮遇到麻烦,主
- 学会了Paint,Canvas的基本用法之后,我们就可以动手开始实践了,先写个简单的图片加载进度条看看。按照惯例,先看效果图,再决定要不要往
- Spring Cloud Gateway是Spring 官方基于Spring 5.0、Spring Boot 2.0和Project Rea
- 一、HashMap概述HashMap基于哈希表的 Map 接口的实现。此实现提供所有可选的映射操作,并允许使用 null 值和 null 键
- 实践过程效果代码public partial class FrmGetColor : Form{ public F
- 上转型对象:子类创建对象 并将这个对象引用赋值给父类的对象。语法格式:Father f=new Son();注意事项:上转型对象是由子类创建
- 前言:现在的手机品牌和型号越来越多,导致我们平时写布局的时候会在个不同的移动设备上显示的效果不同,比如我们的设计稿一个View的大小是300
- 一、代码先上代码(以下这段代码会有多种执行结果)@Testpublic void test_interrupted_thread() thr
- 目录MultipartFile转FileFile转MultipartFile PS:file转base64字符串Multipart
- 一,授权认证客户端请求服务器时,需要通过授权认证许可,方能获取服务器资源,目前比较常见的认证方式有 Basic 、JWT、Cookie。Ht
- java 泛型方法:泛型是什么意思在这就不多说了,而Java中泛型类的定义也比较简单,例如:public class Test
- BeanDefinitionRegistryPostProcessor概述可以看到BeanDefinitionRegistryPostPro
- 本文实例讲述了dotNet中的反射用法。分享给大家供大家参考,具体如下:参考MSDN:ms-help://MS.VSCC.2003/MS.M
- java弱口令检测机制1. 设计要求应具备检测口令的长度和是否在指定字符集合内的能力。应具备检测口令字符逻辑相邻的能力,如aBc,abC等。
- idea如何设置系统环境变量背景最近在接入阿里云的短信服务,在使用阿里云短信服务的SDK过程中想看看SDK中HttpUtil 中public
- 首先使用一个用户提交界面作为举例(文本框,密码框,选择,下拉表单等),效果如下<!DOCTYPE html PUBLIC "
- 一、什么是HTTP协议HTTP是hypertext transfer protocol(超文本传输协议)的简写,它是TCP/IP协议的一个应
- 本文实例讲述了java统计字符串中重复字符出现次数的方法。分享给大家供大家参考,具体如下:package com;import org.ju
- 一,需求来源在开发过程中,可能会要使用Win7 ,Win8 ,Win10等不同版本的系统去做兼容性调试,也有时候会去针对特别的显卡,无线网卡