首页 > 基础资料 博客日记
Spring怎么解决循环依赖问题?
2023-09-15 10:58:05基础资料围观205次
1.什么是循环依赖?
循环依赖是指一个或多个对象之间存在直接或间接的依赖关系,这种依赖关系构成一个环形调用 , 举个例子 : A 依赖B , B依赖C , C依赖A , 这样就形成了循环依赖;
2.spring对循环依赖的处理有三种情况:
①构造器的循环依赖:这种依赖spring是处理不了的,直接拋出BeanCurrentlyInCreationException异常。
②单例模式下的setter循环依赖:通过"三级缓存”处理循环依赖。
③非单例循环依赖:无法处理。
三级缓存的执行逻辑
- 先从“第一级缓存”找对象,有就返回,没有就找“二级缓存”
- 找“二级缓存”,有就返回,没有就找“三级缓存”
- 找“三级缓存”,找到了,就获取对象,放到“二级缓存”,从“三级缓存”移除
3.下面分析单例模式下的setter循环依赖如何解决
Spring的单例对象的初始化主要分为三步:
(1)createBeanInstance:实例化,其实也就是调用对象的构造方法实例化对象
(2)populateBean:填充属性,这一步主要是多bean的依赖属性进行填充
(3)initializeBean:调用spring xml中的init 方法.
从上面讲述的单例bean初始化步骤我们可以知道,循环依赖主要发生在第一,第二部.也就是构造器循 环依赖和field循环依赖.
举例:A的某个field或者setter依赖了B的实例对象,同时B的某个field或者setter依赖了A的实例对象”这种循环依赖的情况.
A首先完成了 初始化的第一步(createBeanINstance实例化),并且将自己提前曝光到singletonFactories中.
此时进行初始化的第二步,发现自己依赖对象B,此时就尝试去get(B),发现B还没有被create,所以走 create流程,B在初始化第一步的时候发现自己依赖了对象A,于是尝试get(A),尝试一级缓存 singletonObjects(肯定没有,因为A还没初始化完全),尝试二级缓存earlySingletonObjects(也没 有),尝试三级缓存singletonFactories,由于A通过ObjectFactory将自己提前曝光了,所以B能够通过 ObjectFactory.getObject拿到A对象(虽然A还没有初始化完全,但是总比没有好呀),B拿到A对象后顺利 完成了初始化阶段1,2,3,完全初始化之后将自己放入到一级缓存singletonObjects中.
此时返回A中,A此时能拿到B的对象顺利完成自己的初始化阶段2,3,最终A也完成了初始化,进去了 一级缓存singletonObjects中,而且更加幸运的是,由于B拿到了A的对象引用,所以B现在hold住的A对 象完成了初始化.
本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若内容造成侵权/违法违规/事实不符,请联系邮箱:jacktools123@163.com进行投诉反馈,一经查实,立即删除!
标签: