| |
|
开发:
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循环依赖流程分析 |
问题 我们都知道在spring中,如果两个bean,相互依赖,那么就会出现循环依赖问题,如果spring对这种问题不进行处理的话,那么就会导致创建bean?失败,所以这就是传说中的三级缓存解决循环依赖的问题。 问题一:相互依赖?从上面的流程图中我们就遇到了循环依赖的问题,也就是在创建BService?的时候,依赖了AService,难道我们再次触发创建AService的流程吗,答案是肯定不行,为了解决这个问题,我们就需要知道哪些bean是正在创建中。 ????????在上面流程中,如果我们增加一个集合,用来存放正在创建的bean,同时用一个map来存放,实例化得到的普通对象,理论上这样我们就可以打破中循环依赖,因为我们在创建BService的时候,可以从map中获得Aservice的对象,并且进行赋值,然后完成创建Bean的生命周期。 ?问题二:代理对象? ? ? ? 上面的解决方案在没有AOP的情况下是没有问题的,但是如果我们在初始化后需要AOP,也就说我们AService,在初始化后需要AOP,这个时候我们都知道会产生一个AService的代理对象,并且最终放在单例池中,但是如果按照上面的解决方案,我们赋值给BService的属性是个普通对象,这肯定是不可以的,所以上面的解决方案需要改进。 这里最大的问题就是,我们怎么知道到底是需要赋值普通对象还是代理对象呢?所以在spring?的源码中引入了一个第三级缓存singletonFactories。这个map中的value存放的是一个Lamda表达式,也就是一个段代码逻辑,这个逻辑就是用来判断是否需要AOP的。 首先,singletonFactories中存的是某个beanName对应的ObjectFactory,在bean的生命周期中,生成完原始对象之后,就会构造一个ObjectFactory存入singletonFactories中。这个ObjectFactory是一个函数式接口,所以支持Lambda表达式:() -> getEarlyBeanReference(beanName, mbd, bean) 上面的Lambda表达式就是一个ObjectFactory,执行该Lambda表达式就会去执行getEarlyBeanReference方法,而该方法如下:
该方法会去执行SmartInstantiationAwareBeanPostProcessor中的getEarlyBeanReference方法,而这个接口下的实现类中只有两个类实现了这个方法,一个是AbstractAutoProxyCreator,一个是InstantiationAwareBeanPostProcessorAdapter,它的实现如下:
在整个Spring中,默认就只有AbstractAutoProxyCreator真正意义上实现了getEarlyBeanReference方法,而该类就是用来进行AOP的。上文提到的AnnotationAwareAspectJAutoProxyCreator的父类就是AbstractAutoProxyCreator。 那么getEarlyBeanReference方法到底在干什么? 首先得到一个cachekey,cachekey就是beanName。 然后把beanName和bean(这是原始对象)存入earlyProxyReferences中 调用wrapIfNecessary进行AOP,得到一个代理对象。 ?这样我们就很好解决了普通对象还是代理对象的问题了,但是这里仍然存在一个问题,大家思考一下,如果我们此时还有一个CService也依赖了AService。 问题三:多次生成代理对象? ? ? ? 为了解决上面抛出来的问题,在spring中引入了二级缓存earlySingletonObjects,也就是把我们生成的无论是代理对象还是普通对象,都缓存起来,这样其他的bean出现依赖的情况,可以直接从这个缓存中获得,不用重新生成一个代理对象,这样就保证了我们AService的唯一性。 至此,通过引入三级缓存解决了,循环依赖的问题: 总结三级缓存是通用的叫法。 一级缓存为:singletonObjects?二级缓存为:earlySingletonObjects?三级缓存为**:singletonFactories**?? 先稍微解释一下这三个缓存的作用,后面详细分析:
|
|
|
上一篇文章 下一篇文章 查看所有文章 |
|
开发:
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/24 1:14:24- |
|
网站联系: qq:121756557 email:121756557@qq.com IT数码 |