spring循环依赖
// A依赖了B
class A{
public B b;
}
// B依赖了A
class B{
public A a;
}
以上就会出现循环依赖,解决方法,二级三级缓存
-
bean的生命周期:
- spring扫描class文件生成beanDefinition
- 根据得到的beanDefinition生成bean
- 根据class推断构造方法
- 填充属性(依赖注入)
- 如果某个对象被aop则要生成代理对象
- 把最终的代理对象放入单例池中,下次获取bean时直接从单例池中获取
-
三级缓存
- 一级缓存 singletonObjects ;里面的bean对象经历了完整的生命周期
- 二级缓存 earlySingletonObjects ;是早前的bean对象
- 三级缓存 singletonFactories; 是创建早期bean对象的工厂
-
如何打破循环依赖
- 通过缓存解决,但是存在问题,这个放入缓存中的是原始对象还是代理对象,这个可能导致b依赖a产生冲突
-
三级缓存 singletonFactories
- 首先在bean的生命周期内会构造一个objectFactory存入singletonFactories中,这是一个函数接口,为了创建aop代理对象,如果执行这个则会吧代理对象放入 earlySingletonObjects
- 此时对于a而言,当b创建完后,a继续执行生命周期,按照他本身逻辑进行aop,此时会判断当前beanName是否在earlyProxyRefenrences中。经过aop判断后要把a对应的对象放入singletonObjects中,要放入的是代理对象,所以会从earlySingletonObjects中取。至此循环依赖结束
- 注意 earlyProxyReferences 这也是一个缓存,记录原始对象是否进行了aop
-
为什么一定要三级缓存
- 我的理解,为了遵守bean的生命周期设计
- 不知何时吧aop代理对象或者原始对象放入earluSingletonObjects中