源码地址:https://github.com/spring-projects/spring-framework
仓库地址:https://gitcode.net/qq_42665745/spring/-/tree/16-third-level-cache
三级缓存解决循环依赖
前提:A依赖B,B依赖A
初始化流程:先按照顺序从一级缓存、二级缓存、三级缓存中取A,不存在A,进行初始化BeanA,先实例化对象A,放入创建A的对象工厂ObjectFactory放入三级缓存,然后进行属性注入,发现依赖B,从缓存中取B,不存在B,进行初始化BeanB,实例化B,将创建B的对象工厂ObjectFactory放入三级缓存,进行属性注入,发现依赖A,从缓存中取A,在三级缓存中找到了A的对象工厂,使用其拿到A的原始引用,这里可能会返回正常对象或者代理对象(半成品对象,未完成属性注入),将其放入二级缓存,清除A的三级缓存,然后B初始化完成,将其放入二级缓存,清除三级缓存,再放入一级缓存,清除二三级缓存。这时回到A的属性注入流程,A取到了B的对象,完成属性注入,初始化完成,将A从二级缓存移到一级缓存,清除二级缓存。
总结一下在Bean声明周期中,执行代理的时机
1.从三级缓存获取Bean的早期引用(指的是Bean在实例化后但在完全初始化之前的引用),spring会尝试对Bean做Aop代理,所以从三级缓存获取的引用,有可能是半成品Bean也有可能是AOP代理过的Bean
2.Bean实例化前置钩子 resolveBeforeInstantiation,如果返回了一个实例,创建bean的过程直接结束,直接返回这个实例
3.Bean初始化后置钩子applyBeanPostProcessorsAfterInitialization,spring对所有Bean对象进行AOP代理。如果在三级缓存阶段已经对Bean进行了AOP代理,这里不会重复代理。