三级缓存
  • singletonObjects 一级缓存,用于保存实例化、注入、初始化完成的bean实例。存放最终完整对象的缓存,所以在获取对象是最先判断此处是否存在对象
  • earlySingletonObjects 二级缓存,用于保存实例化完成的bean实例。中间的、过渡的缓存、存放未进行属性赋值时的对象
  • singletonFactories 三级缓存,用于保存bean创建工厂,以便于后面扩展有机会创建代理对象。对象创建好之后尚未进行属性复制前存放的缓存

image.png

v2-1e7bd042df73e47bb951e70b298c96ca_1440w.jpegAB相互依赖为例

当A对象创建前通过getSingleton方法去缓存取数据。
首次,显然为空,那么就会执行createBeanInstance方法通过反射调用构造去实例化A对象。
A对象创建后会调用addSingletonFactory(beanName, () -> getEarlyBeanReference(beanName, mbd, bean))
将A对象放入三级缓存singletonFactories。
通过populateBean方法进行属性赋值,发现属性中有B需要赋值,
这时候通过getBean创建B,在此之前,通过getSingleton方法去缓存取B对象,为空。
执行createBeanInstance方法通过反射调用构造去实例化B对象, B对象创建后,
会调用addSingletonFactory(beanName, () -> getEarlyBeanReference(beanName, mbd, bean))
将B对象放入三级缓存singletonFactories。
通过populateBean方法进行属性赋值,发现属性中有A需要赋值,
通过getBean->doGetBean->getSingleton中判断
首先判断一级缓存singletonObjects,不存在则,判断二级缓存earlySingletonObjects,不存在则从三级缓存singletonFactories获取,将A获取出来后将A从三级缓存提升至二级缓存。
B对象就可以完成属性赋值(只是不完美,因为A对象未完成属性赋值),B对象之后进行生命周期的init和后置处理后,完成创建,将B放入一级缓存中。
A对象的属性赋值得以继续,完成A的属性赋值后,进行生命周期的init和后置处理,A对象也变得完美,将B放入一级缓存中而由于B对象中A存放的是引用,所以当A对象完美后,B中A指向的对象是一个,故B也完美

简述

反射实例化A对象,放到三级缓存,属性赋值发现需要B,反射创建B,放到三级缓存,发现需要a,将三级缓存的A赋值,然后将A提升至二级缓存,生命周期初始化和后置处理,将b放入一级,然后A继续属性 赋值提升至一级
仅使用二级缓存可以用来解决循环依赖的问题,但是前提是这个bean没有被aop进行切面代理,如果这个bean被aop切面代理了两级缓存是无法解决的,不可能每次执行singleFactory.getObject()方法都给我产生一个新的代理对象,所以还要借助另外一个缓存来保存产生的代理对象
需要涉及 三级缓存、 提前暴露bean对象、aop

缓存的放置时间跟删除时间

三级缓存:创建实例对象 addSingletonFactory
二级缓存:第一次从三级缓存获取对象,删除三级缓存 getSingleton
一级缓存:生成完整bean对象之后,删除二三级缓存 addSingleton