java

关注公众号 jb51net

关闭
首页 > 软件编程 > java > Spring循环依赖

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

作者:编程の小白

本文给大家分享Spring使用三级缓存解决循环依赖的问题,本文通过实例代码给大家介绍的非常详细,对大家的学习或工作具有一定的参考借鉴价值,需要的朋友参考下吧

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()

循环依赖的对象在三级缓存中的迁移过程

然后接着回来创建 A,此时 B 已经完成创建,直接从一级缓存中拿到 B,完成 A 的创建,并将 A 添加到单例池,删除二级缓存中的 A

图示:

以上就是Spring使用三级缓存解决循环依赖的详细内容,更多关于Spring循环依赖的资料请关注脚本之家其它相关文章!

您可能感兴趣的文章:
阅读全文