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

图示:

Spring使用 * 缓存解决循环依赖的问题

来源:https://www.cnblogs.com/fkPrograming/p/14873803.html

标签:Spring, , 缓存,循环依赖
0
投稿

猜你喜欢

  • spring基于注解配置实现事务控制操作

    2021-12-07 11:58:24
  • java图的深度优先遍历实现随机生成迷宫

    2023-06-26 06:06:05
  • Java编程实现帕斯卡三角形代码示例

    2023-11-02 08:08:24
  • C# 设计模式系列教程-外观模式

    2023-01-08 18:44:40
  • Android自定义控件之电话拨打小键盘

    2022-11-17 21:52:08
  • java8新特性 stream流的方式遍历集合和数组操作

    2023-03-29 10:49:25
  • Spring Boot应用Docker化的步骤详解

    2023-10-12 11:47:36
  • Java8处理集合的优雅姿势之Stream

    2023-03-14 09:31:48
  • C语言安全编码之数组索引位的合法范围

    2021-12-08 06:09:51
  • spring-boot-maven-plugin报红解决方案(亲测有效)

    2022-07-23 01:16:46
  • SpringBoot多环境开发与日志小结

    2021-09-18 19:05:44
  • flutter 怎么实现app整体灰色效果

    2023-01-24 21:23:22
  • 自定义视图view使用Canvas实现手写板和涂鸦功能

    2022-02-22 17:00:43
  • 利用C#操作WMI指南

    2022-05-07 18:02:42
  • SpringCloud如何使用Eureka实现服务之间的传递数据

    2022-02-17 18:47:37
  • 解决JAVA非对称加密不同系统加密结果不一致的问题

    2022-02-13 06:43:56
  • C#中static静态变量的用法实例

    2022-12-16 07:47:44
  • java多线程Synchronized实现可见性原理解析

    2021-08-26 02:10:02
  • java实现递归文件列表的方法

    2022-10-13 13:17:00
  • Unity实现颜色渐变滑动条

    2023-11-28 10:54:51
  • asp之家 软件编程 m.aspxhome.com