三级缓存和代理
场景一:AB循环引用,A会被AOP处理
-
A实例化,入三级缓存(
getEarlyBeanReference
),填充属性引起B的处理A:位于三级缓存,是target,属性填充阶段
-
B实例化,入三级缓存,填充属性
- 查三级缓存,触发
getEarlyBeanReference
执行,此阶段会进行AspectJAwareAdvisorAutoProxyCreator
处理,返回A#proxy - A#proxy移动到二级缓存
- B属性填充完成
- 后续操作:初始化,其他处理,移动到一级缓存
A:位于二级缓存,是targer
B:位于一级缓存,是target,B.a是proxy
- 查三级缓存,触发
-
继续A的处理:属性填充,初始化,a作为早期引用暴露则进行替换 查二级缓存的proxy替换当前的target,移动到一级缓存
问题:为什么需要三级缓存?
A.a位于三级缓存,是target,然后嵌套引起B实例化,将会通过三级缓存获取A触发getEarlyBeanReference
-> AspectJAwareAdvisorAutoProxyCreator
生成A的proxy,所以这个时候(三级缓存的target移除,二级缓存新增A的proxy)。
场景:AB循环引用,AB都经过AOP处理生成proxy
B会在初始化(Aware,前置,自定义init-method,后置处理)的后置处理阶段,进行AspectJAwareAdvisorAutoProxyCreator
处理,返回proxy,最后移动到一级缓存
总结
- 循环引用带来的提前暴露,在查三级缓存触发
getEarlyBeanReference
,从而AspectJAwareAdvisorAutoProxyCreator
创建proxy,然后移动到二级缓存; - 正常流程的代理,则在后置处理阶段,触发
AspectJAwareAdvisorAutoProxyCreator
创建proxy,然后移动到一级缓存。