| |
|
开发:
C++知识库
Java知识库
JavaScript
Python
PHP知识库
人工智能
区块链
大数据
移动开发
嵌入式
开发工具
数据结构与算法
开发测试
游戏开发
网络协议
系统运维
教程: HTML教程 CSS教程 JavaScript教程 Go语言教程 JQuery教程 VUE教程 VUE3教程 Bootstrap教程 SQL数据库教程 C语言教程 C++教程 Java教程 Python教程 Python3教程 C#教程 数码: 电脑 笔记本 显卡 显示器 固态硬盘 硬盘 耳机 手机 iphone vivo oppo 小米 华为 单反 装机 图拉丁 |
-> Java知识库 -> 【小明】谈谈你对Spring三级缓存和循环依赖的理解【建议收藏】 -> 正文阅读 |
|
[Java知识库]【小明】谈谈你对Spring三级缓存和循环依赖的理解【建议收藏】 |
一、什么是循环依赖?什么是三级缓存? 【什么是循环依赖】什么是循环依赖很好理解,当我们代码中出现,形如BeanA类中依赖注入BeanB类,BeanB类依赖注入A类时,在IOC过程中creaBean实例化A之后,发现并不能直接initbeanA对象,需要注入B对象,发现对象池里还没有B对象。通过构建函数创建B对象的实例化。又因B对象需要注入A对象,发现对象池里还没有A对象,就会套娃。 【三级缓存】三级缓存实际上就是三个Map对象,从存放对象的顺序开始 ????????三级缓存singletonFactories存放ObjectFactory,传入的是匿名内部类,ObjectFactory.getObject() 方法最终会调用getEarlyBeanReference()进行处理,返回创建bean实例化的lambda表达式。
二、三级缓存如何解决循环依赖? 【如何解决循环依赖】Spring解决循环依赖的核心思想在于提前曝光,首先创建实例化A,并在三级缓存singletonFactories中保存实例化A的lambda表达式以便获取A实例,当我没有循环依赖和AOP时,这个三级缓存singletonFactories是没用在后续用到的。 三、使用二级缓存能不能解决循环依赖? 一定是不行,我们只保留二级缓存有两个可能性保留一二singletonObjects和earlySingletonObjects,或者一三singletonObjects和singletonFactories 【只保留一二singletonObjects和earlySingletonObjects】 流程可以这样走:实例化A ->将半成品的A放入earlySingletonObjects中 ->填充A的属性时发现取不到B->实例化B->将半成品的B放入earlySingletonObjects中->从earlySingletonObjects中取出A填充B的属性->将成品B放入singletonObjects,并从earlySingletonObjects中删除B->将B填充到A的属性中->将成品A放入singletonObjects并删除earlySingletonObjects。 这样的流程是线程安全的,不过如果A上加个切面(AOP),这种做法就没法满足需求了,因为earlySingletonObjects中存放的都是原始对象,而我们需要注入的其实是A的代理对象。 【只保留一三singletonObjects和singletonFactories】 流程是这样的:实例化A ->创建A的对象工厂并放入singletonFactories中 ->填充A的属性时发现取不到B->实例化B->创建B的对象工厂并放入singletonFactories中->从singletonFactories中获取A的对象工厂并获取A填充到B中->将成品B放入singletonObjects,并从singletonFactories中删除B的对象工厂->将B填充到A的属性中->将成品A放入singletonObjects并删除A的对象工厂。 同样,这样的流程也适用于普通的IOC已经有并发的场景,但如果A上加个切面(AOP)的话,这种情况也无法满足需求。 因为拿到ObjectFactory对象后,调用ObjectFactory.getObject()方法最终会调用getEarlyBeanReference()方法,getEarlyBeanReference这个方法每次从三级缓存中拿到singleFactory对象,执行getObject()方法又会产生新的代理对象 所有这里我们要借助二级缓存来解决这个问题,将执行了singleFactory.getObject()产生的对象放到二级缓存中去,后面去二级缓存中拿,没必要再执行一遍singletonFactory.getObject()方法再产生一个新的代理对象,保证始终只有一个代理对象。 getSingleton()、getEarlyBeanReference() 源码如下
|
|
|
上一篇文章 下一篇文章 查看所有文章 |
|
开发:
C++知识库
Java知识库
JavaScript
Python
PHP知识库
人工智能
区块链
大数据
移动开发
嵌入式
开发工具
数据结构与算法
开发测试
游戏开发
网络协议
系统运维
教程: HTML教程 CSS教程 JavaScript教程 Go语言教程 JQuery教程 VUE教程 VUE3教程 Bootstrap教程 SQL数据库教程 C语言教程 C++教程 Java教程 Python教程 Python3教程 C#教程 数码: 电脑 笔记本 显卡 显示器 固态硬盘 硬盘 耳机 手机 iphone vivo oppo 小米 华为 单反 装机 图拉丁 |
360图书馆 购物 三丰科技 阅读网 日历 万年历 2024年11日历 | -2024/11/23 16:29:12- |
|
网站联系: qq:121756557 email:121756557@qq.com IT数码 |