赞
踩
spring使用三级缓存处理了循环依赖问题,并且第三级缓存中的对象工厂getObject()
的时候会牵扯到AOP,一般来说,getObject()
之后就会放到二级缓存中。
那么,为什么不能去掉三级缓存,每次都创建好代理版本放到二级缓存中完事?
getObject()
的时候在SmartInstanitiaionAwareBeanPostProcessor
里面代理BeanPostProcessor
的回调代理getObject
会被调到的情况,只能是存在循环依赖的情况:
即,A工厂放入三级缓存,A准备属性注入B,B工厂放入三级缓存,B raw bean准备属性注入A,找到三级缓存中的A工厂,调用getObject
。
工厂其实包括两个东西,一个是raw bean,一个是lambda表达式,里面会有个特殊的postProcessor进行AOP代理。
如果不存在循环依赖,则A的属性赋值过程中都不会间接调用到getObject
方法,那么就往下走去到初始化阶段里面使用BeanPostProcessor
的回调进行动态代理。
不知道从哪里看见的,说是Spring设计初衷就是要Bean完全属性赋值完成之后再进行AOP(对应生命周期是初始化阶段),因此,初始化阶段会有BeanPostProcessor
的回调方法进行AOP代理,此时的target都是赋值完整的target。
但是在存在循环依赖的时候,这个设计初衷就被打破了。
举个例子,仅考虑2个对象AB的相互依赖,AB都有代理逻辑。
实例化后的『A原始Bean』装配B
=> 实例化后的『B原始Bean』装配A
,那么这个时候装配的A必须进行代理,否则装配的就是原始A了!所以B调用了A工厂的getObject
提前进行代理,然后注入到B中,B就可以顺利属性赋值完成,然后进入初始化阶段,B在初始化阶段进行AOP。
既然A提前代理了,当A到初始化阶段再次碰到代理逻辑怎么办?
实际上会判断下是否已经提前代理过了,如果代理过了,初始化阶段的代理逻辑就不做了,用之前的代理Bean作为结果。
一级缓存:代理过 & 属性赋值 完成的Bean (注意,仅指自身属性赋值完整,属性的属性有没有赋值不管)
二级缓存:提前代理好了 & 属性未完全赋值
三级缓存:对象工厂,包含提前代理的逻辑
Copyright © 2003-2013 www.wpsshop.cn 版权所有,并保留所有权利。