java中的循环依赖以及解决方案
java中的循环依赖以及解决方案
什么是循环依赖
我们创建了两个类,一个类A,一个类B(当然循环依赖不一定只是两个类,可能是多个以及以上的类),在A里面引入了B,在B里面引入了A,这时候就构成了一个循环问题,看似无止境,无尽头 他们之间的关系如下
spring循环依赖解决方案
这些类在我们spring框架启动的时候,会进行有序的扫描并实例化 拿A举例: 1.实例化A 2.将a对象放入到指定的三级缓存对象 3.setName…当到成员变量b的时候,发现B上面有@Atowired注解,就会触发B的实例化过程
-
实例化B 将b对象放入到指定的三级缓存对象 setName…当到成员变量a的时候,就会去spring的三级缓存里面直接去拿 B的实例化完成
4.拿到b的实例化对象
注意:构造器注入构成的循环依赖是无法解决的!只能抛出BeanCurrentlyInCreationException异常表示循环依赖,构造函数之间发生循环依赖(A的构造方法中依赖B,B的构造方法中依赖A),程序会在运行时一直循环调用最终导致内存溢出。 错误原因: 根本原因是 Spring 解决循环依赖依靠的是 Bean 的 中间态 这个概念,而中间态指的是 已经实例化,但未初始化的状态。而构造器负责的是实例化,故无法解决构造器循环依赖。
spring的三级缓存
singletonObject:一级缓存,存放完全实例化且属性赋值完成的 Bean ,可以直接使用 earlySingletonObject:二级缓存,存放早期 Bean 的引用,尚未装配属性的 Bean singletonFactories:三级缓存,存放实例化完成的 Bean 工厂