阿里面试官居然不懂Spring是如何处理循环依赖的?
BeanPostProcessor的after方法中会完成动态代理商对象的创立。
在创立代理商对象之前,能否需要原始对象?
需要原始对象!若刚开始先创立了原始对象,而后又创立了代理商对象,则对外暴露引用时,应该用原始对象还是用代理商对象呢?
程序是写死的,没那么智能,说要判断用什么对象,所以我们需要保证,当bean需要被引用时,必需给出一个最终的结果:要么是原始对象,要么是代理商对象,当生成代理商对象时,原始对象会被覆盖掉。怎样确定对象什么时候对外暴露或者者说对外引用呢?
无法确定!所以有了三级缓存这个骚操作!有了三级缓存,每次在创立完对象后,不是直接把对象放到一级或者二级缓存,而是先将一个lambda表达式放到三级缓存中,当需要被引用时,会优先从三级缓存中获取到lambda,而后根据lambda表达式解决结果判断究竟是原始对象还是代理商对象。
getEarlyBeanReference在此方法中已唯一确定了对外暴露的对象究竟是原始对象还是代理商对象。
当Bean产生循环依赖时,比方BeanA的构造方法依赖BeanB作为成员需要注入,BeanB也依赖BeanA,你觉得会出现什么问题呢?又有哪些处理方式呢?
通过set方法去解决,背后的原理其实是缓存。
主要处理方式:
三级缓存
singletonObjects
一级缓存, Cache of singleton objects
bean name –> bean instance。
存放完整对象。
earlySingletonObjects
二级缓存, Cache of early singleton objects
bean name –> bean instance 提前曝光的BEAN缓存。
存放半成品对象。
singletonFactories
三级缓存, Cache of singleton factories
bean name –> ObjectFactory。需要的对象被代理商时,就必需使用三级缓存(否则二级就够了)。处理循环依赖中存在aop的问题
存放 lambda 表达式和对象名称的映射。
- spring中已经有了循环依赖的处理方案,为什么项目中还会出现循环依赖的问题?
spring中现有的处理循环依赖问题的方案只是一种预防机制, 当符合此情况的时候可以处理,但是在实际的场景中会存在很多不匹配的情况,构造器的循环依赖是无法处理的!
带着aop的实现来重新走一下刚刚执行的逻辑, 体会各个对象在程序运行过程中的流转过程,对象的三个缓存中的迁移过程,画个图,总结下,debug下,
起始断点的入口在:finishBeanFactorylnitialization方法。
image
1. 本站所有资源来源于用户上传和网络,如有侵权请邮件联系站长!
2. 分享目的仅供大家学习和交流,您必须在下载后24小时内删除!
3. 不得使用于非法商业用途,不得违反国家法律。否则后果自负!
4. 本站提供的源码、模板、插件等等其他资源,都不包含技术服务请大家谅解!
5. 如有链接无法下载、失效或广告,请联系管理员处理!
6. 本站资源售价只是摆设,本站源码仅提供给会员学习使用!
7. 如遇到加密压缩包,请使用360解压,如遇到无法解压的请联系管理员
开心源码网 » 阿里面试官居然不懂Spring是如何处理循环依赖的?