spring为什么不能只用一二级缓存来解决循环依赖?
Spring bean注入流程
类实例化 -> 属性注入 -> 执行初始化方法 -> (如果有需要)生成代理对象 -> 使用
二级缓存存在的问题
举例说明:A、B两个类相互依赖,初始化A的时候,
第一步实例化A完成(原始实例放入二级缓存),注入依赖属性B,一级缓存查询B没有,二级缓存查询B没有,
初始化B(放入缓存),注入依赖属性A,一级缓存查询A没有,二级缓存查询A注入(此时A是原始实例,未被代理),生成代理对象B,移入一级缓存,继续A属性注入(B的代理对象),A初始化完成。
B中的依赖对象A是未代理的,存在问题(环境中存在代理和未代理的两种类型的同一个对象A)。
如果上述流程放入二级缓存的是代理对象,则和spring bean生成流程(实例最后生成代理对象)相悖。
三级缓存解决的问题
A、B两个类相互依赖,初始化A的时候,第一步实例化A完成(生成对象工厂实例放入三级缓存),注入依赖属性B,一级缓存查询B没有,二级缓存查询B没有,
初始化B(生成对象工厂实例放入三级缓存),注入依赖属性A,一级缓存查询A没有,二级缓存查询A没有,三级缓存查询到A的对象工厂,生成A的代理对象,放入到二级缓存,注入A的代理对象完成,生成代理对象B,移入一级缓存。
继续A属性注入(B的代理对象),A初始化,生成A的代理对象,发现A的代理对象已存在,则跳过,放入一级缓存。此时A的代理对象也是提前生成的,但是仅针对循环依赖提前生成。
三级缓存正常生成流程
第一步实例化A完成(生成对象工厂实例放入三级缓存,此时虽然放入三级缓存,但没有生成代理对象),注入属性,执行初始化方法,生成代理对象,移入一级缓存。
其中创建AOP代理对象的子类是AbstractAutoProxyCreator,它实现了postProcessAfterInitialization方法,先判断初始化完成后的bean是否已经被动态代理,若已处理过,则直接返回,如果不需要动态代理,也直接返回;若需要处理,则生成动态代理,保存到一级缓存中。
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· 分享4款.NET开源、免费、实用的商城系统
· 全程不用写代码,我用AI程序员写了一个飞机大战
· MongoDB 8.0这个新功能碉堡了,比商业数据库还牛
· 白话解读 Dapr 1.15:你的「微服务管家」又秀新绝活了
· 上周热点回顾(2.24-3.2)