三级缓存和代理
场景一: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,然后移动到一级缓存。
版权声明:本文为qq_31854267原创文章,遵循CC 4.0 BY-SA版权协议,转载请附上原文出处链接和本声明。