BeanPostProcessor的after方法中会完成动态代理商对象的创立。
在创立代理商对象之前,能否需要原始对象?
需要原始对象!
若刚开始先创立了原始对象,而后又创立了代理商对象,则对外暴露引用时,应该用原始对象还是用代理商对象呢?
程序是写死的,没那么智能,说要判断用什么对象,所以我们需要保证,当bean需要被引用时,必需给出一个最终的结果:要么是原始对象,要么是代理商对象,当生成代理商对象时,原始对象会被覆盖掉。
怎样确定对象什么时候对外暴露或者者说对外引用呢?
无法确定!所以有了三级缓存这个骚操作!有了三级缓存,每次在创立完对象后,不是直接把对象放到一级或者二级缓存,而是先将一个lambda表达式放到三级缓存中,当需要被引用时,会优先从三级缓存中获取到lambda,而后根据lambda表达式解决结果判断究竟是原始对象还是代理商对象。
getEarlyBeanReference在此方法中已唯一确定了对外暴露的对象究竟是原始对象还是代理商对象。
当Bean产生循环依赖时,比方BeanA的构造方法依赖BeanB作为成员需要注入,BeanB也依赖BeanA,你觉得会出现什么问题呢?又有哪些处理方式呢?
通过set方法去解决,背后的原理其实是缓存。
主要处理方式:
一级缓存, Cache of singleton objects
bean name --> bean instance。
存放完整对象。
二级缓存, Cache of early singleton objects
bean name --> bean instance 提前曝光的BEAN缓存。
存放半成品对象。
三级缓存, Cache of singleton factories
bean name --> ObjectFactory。需要的对象被代理商时,就必需使用三级缓存(否则二级就够了)。处理循环依赖中存在aop的问题
存放 lambda 表达式和对象名称的映射。
带着aop的实现来重新走一下刚刚执行的逻辑, 体会各个对象在程序运行过程中的流转过程,对象的三个缓存中的迁移过程,画个图,总结下,debug下,
起始断点的入口在:finishBeanFactorylnitialization方法。