Spring源码循环依赖
一级缓存:存储单例Bean的Map对象。
二级缓存:为了将成熟Bean和纯净Bean分离开来,职责更明确,代码更容易维护,避免由于多线程的环境下读取到不完整的Bean。二级缓存不能存储原生对象。
三级缓存:解决因为AOP,创建动态代理导致的问题。存储函数式接口,钩子函数。
如果没有出现循环依赖,则会在初始化之后通过BeanPostProcessor创建动态代理。
如果出现了循环依赖,则会在实例化之后通过BeanPostProcessor创建动态代理。(提前了)怎么判断当前是否出现了循环依赖呢?可以判断在二级缓存中是否有对应Bean。可以添加一个循环依赖的标识。比如标识为正在创建的Bean。singletonCurrentlyInCreation。
动态代理放入到二级缓存中会有什么问题:
更多的是单一职责原则,其实问题不大。将钩子函数通过函数式接口传递到getSinleton)()方法,判断二级缓存中是否包含对应Bean,并且创建对应的动态代理对象,实现AOP。代码解耦,代码看起来更好看,更易于维护。
正常情况下会在初始化之后创建动态代理。
模拟代码如下:
bean初始化完成之后还需要remove掉二级缓存和三级缓存,没必要存在了。
多例不能解决循环依赖,多例都不会往缓存中放入。
如果您觉得阅读本文对您有帮助,请点一下“推荐”按钮,您的“推荐”将是我最大的写作动力!欢迎各位转载,但是未经作者本人同意,转载文章之后必须在文章页面明显位置给出作者和原文连接,否则保留追究法律责任的权利。
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· 全程不用写代码,我用AI程序员写了一个飞机大战
· DeepSeek 开源周回顾「GitHub 热点速览」
· 记一次.NET内存居高不下排查解决与启示
· MongoDB 8.0这个新功能碉堡了,比商业数据库还牛
· .NET10 - 预览版1新功能体验(一)
2019-11-19 局域网两台主机通过网络共享文件