首页 > 编程语言 > 详细

Spring bean创建之循环依赖与三级缓存

时间:2021-06-17 23:09:10      阅读:51      评论:0      收藏:0      [点我收藏+]

Spring bean创建之循环依赖与三级缓存

循环依赖

多个对象之间互相引用形成环

技术分享图片

如果使用普通new方法创建,对象之间会循环创建导致OOM

三级缓存
  • 一级缓存:singletonObjects
  • 二级缓存:earlySingletonObjects
  • 三级缓存:singletonFactories

在创建对象时会按照:一级--->二级--->三级的顺序尝试获取对象

技术分享图片

bean的创建

对于ClassPathXmlApplicationContext获取bean对象,前置有一系列方法初始化容器、定义BeanFactoryPostProcess、国际化、多播器等的准备工作。

技术分享图片

核心对象创建对象方法:

// Instantiate all remaining (non-lazy-init) singletons.
finishBeanFactoryInitialization(beanFactory);

技术分享图片

堆栈信息:

技术分享图片

之后将会循环遍历需要创建bean对象的列表,调用getBean方法

技术分享图片

技术分享图片

尝试从三级缓存中获取:
技术分享图片

获取不到,只能创建对象:

技术分享图片

将会调用lambda表达式中的createBean进行对象的创建

技术分享图片

到此对象已经实例化完成,需要进行初始化,不过在调用populateBeanff初始化前,将调用addSingletonFactory方法将包含自身实例的objectFactory放入第三级缓存中。

技术分享图片

具体的实现方法:

技术分享图片

技术分享图片

为了解决依赖的对象不存在的问题,同样是依靠getBean方法解决

技术分享图片

不过这一次,在第三级缓存中可以获取到循环依赖的对象(假设是两个对象之间循环依赖,开始创建的是A对象,目前创建的是B对象,此时B对象可以从第三级缓存中获取到实例化的A对象,直接装配到B对象中)

技术分享图片

此时获取到只实例化的A对象后,将第三级缓存中的A对象移除,放到二级缓存中,值得注意的是B对象在初始化前也会将自己放入三级缓存中,由于自身的依赖已经解决,B对象在getSingleton方法返回前又会将自己的从三级缓存中删除放到一级缓存中。

技术分享图片

至此B对象已经初始化完成,只需将属性注入到A中即可,而A对象被初始化完成之后也会将自己从二三级缓存中删除,放入到一级缓存中,至此A对象创建完成。

在for循环遍历下一个需要创建的Bean时,会直接从缓存中获取,不需要再实例化、初始化。

整个过程的堆栈信息:

技术分享图片

流程图:

技术分享图片

Spring bean创建之循环依赖与三级缓存

原文:https://www.cnblogs.com/kmchen/p/14897410.html

(0)
(0)
   
举报
评论 一句话评论(0
关于我们 - 联系我们 - 留言反馈 - 联系我们:wmxa8@hotmail.com
© 2014 bubuko.com 版权所有
打开技术之扣,分享程序人生!