Spring中Bean的循环依赖问题

1.什么是Bean的循环依赖?

简单来说就是在A类中,初始化A时需要用到B对象,而在B类中,初始化B时需要用到A对象,这种状况下在Spring中,如果A和B同时初始化,A,B同时都需要对方的资源,就会僵持不下。这也就是Spring中的循环依赖问题。Spring框架对这种属性所产生的循环依赖的解决办法很简单,就是使用@Autowired注解,如下:

java 复制代码
public class BeanA {
    @Autowired
    private BeanB beanB;
}

public class BeanB {
    @Autowired
    private BeanA beanA;
}

对于构造方法的循环依赖,Spring可采用@Lazy或者使用Setter()方法去解决,这里我们不做讨论。

2.@Autowired

在Spring中,我们可以使用@Autowired注解对属性或者方法参数进行标注,会从IOC容器中拿到对应的实例自动注入。

3.解决循环依赖的具体细节

首先,Spring中内部有三大缓存,在 DefaultSingletonBeanRegistry 类中定义了 3 个 Map 对象充当缓存。分别是:

  • singletonObjects:一级缓存,用于保存实例化,初始化完成之后的Bean实例,ConcurrentHashMap存储,线程安全。
  • earlysingletonObjects:二级缓存,用于保存实例化完成,还未初始化完的Bean实例,属于提前暴露。
  • singleFactories:三级缓存,存放生成Bean的工厂,也相当是存放了获取Bean的一个回调方式。

具体实现:

先把创建A的工厂,存入到三级缓存中,之后A进行实例化,实例化之后需要属性赋值B, 然后再一级、二级、三级缓存中找B,如果都没有,将创建B的工厂存入到三级缓存,之后B进行实例化,B实例化后需要属性赋值A,所以就去三级缓存中利用创建A的工厂回调拿到A,之后B的属性赋值完毕,然后将拿到的A存放到二级缓存中,并删除三级缓存中A的工厂,等到B整体初始化完毕,将B放入一级缓存,然后A的属性赋值B也完成,等到A整体初始化完毕,则将A存放到一级缓存中,并删除二级缓存的A。

相关推荐
Ro Jace17 分钟前
计算机专业基础教材
java·开发语言
mango_mangojuice35 分钟前
Linux学习笔记(make/Makefile)1.23
java·linux·前端·笔记·学习
程序员侠客行39 分钟前
Mybatis连接池实现及池化模式
java·后端·架构·mybatis
时艰.42 分钟前
Java 并发编程 — 并发容器 + CPU 缓存 + Disruptor
java·开发语言·缓存
丶小鱼丶1 小时前
并发编程之【优雅地结束线程的执行】
java
市场部需要一个软件开发岗位1 小时前
JAVA开发常见安全问题:Cookie 中明文存储用户名、密码
android·java·安全
忆~遂愿1 小时前
GE 引擎进阶:依赖图的原子性管理与异构算子协作调度
java·开发语言·人工智能
MZ_ZXD0011 小时前
springboot旅游信息管理系统-计算机毕业设计源码21675
java·c++·vue.js·spring boot·python·django·php
PP东1 小时前
Flowable学习(二)——Flowable概念学习
java·后端·学习·flowable
ManThink Technology1 小时前
如何使用EBHelper 简化EdgeBus的代码编写?
java·前端·网络