Spring 循环依赖问题

Spring 的循环依赖问题是指

需要初始化的Bean A需要依赖另一个BeanB

但是BeanB 也需要依赖Bean A 导致两个Bean的初始化都无法完成

Spring是通过三级缓存机制解决循环依赖问题的

其实若是不考虑AOP 二级缓存就完全足够解决这个问题

核心思路是 提前暴露没有完全初始化的Bean、

实例化完BeanA 后就把这个Bean放入二级缓存中

这样初始化BeanB时 就可以到二级缓存中拿到这个初始化了一半的BeanA

这样BeanB就可以完成初始化 BeanA也能完成依赖注入后结束初始化

但是问题的关键是Spring的一大特性便是AOP

若是Bean A是需要动态代理的Bean BeanB直接把BaenA 注入肯定是不对的

需要注入代理后的对象

那我们把BeanA代理后的对象放入二级缓存可以吗?

有两方面的原因 导致不能这么做

1.动态代理注入是在Bean初始化完成之后做的,此时A尚未完成初始化,拿不到动态代理类

2.假如能提前拿到A的代理对象 那岂不是A初始化完之后又会重新代理一次? 所以不行

Spring的解决是通过三级缓存

一级缓存:存完全初始化后的对象

二级缓存:存初始化了一半的对象

三级缓存:存初始化对象所用的ObjectFactory,当一级缓存二级缓存都没有需要的Bean时就会把这个Bean的工厂放到三级缓存中

有个疑问是,为什么用ObjectFactory就可以提前获取到动态代理类的对象?又是怎么避免初始化完成后再次代理的呢?

1.ObjectFactory内会判断是否为代理对象,若是代理对象则提前生成代理对象并返回

2.会有代理对象标记,若当前Bean已经被代理过 会被标记 不会二次初始化

获取到代理对象后会放入二级缓存,若此时还有其他Baen也要获取A 则直接返回二级缓存中的对象,不会再次生成代理对象,这也是二级缓存的作用

那为什么用ObjectFactory就没有提前代理的问题呢?

相关推荐
ZYJCSZKJ1 小时前
基于地理位置围栏的短视频POI团购系统:LBS空间索引与流量分发实践
java·服务器·数据库
mldong7 小时前
引擎从不发一条消息:jeeflow 的两类扩展点与消息模块的分工
java·架构
君顾17 小时前
智慧零售实战指南:从技术架构到落地方案全解析
java·开发语言·零售
zhanghe6878 小时前
es的密码带有特殊字符,导出
java
pnoker8 小时前
IoT DC3 概念解读:把设备抽象成一套语义模板——位号、指令、事件与面向智能体的设备建模
java·人工智能·物联网·iot·dc3
my_realmy8 小时前
Java SE 基础学习笔记(一):面向对象、继承多态、抽象接口与异常(JDK 8)
java·多线程·并发··生产者消费者模式
天远数科9 小时前
风险治理实战:基于天远车信盟出险构建自动化理赔核保流水线
java·网络·人工智能·自动化
Mr.朱鹏9 小时前
Linux 服务器 LVM 根分区在线动态扩容
linux·服务器·数据库
骇客野人9 小时前
SpringBoot电商系统用户注册、登录、留存及数据埋点设计与落地实施方案
java·spring boot·后端
摇滚侠9 小时前
《SpringBoot 3:入门与应用实战》第 12 章 JDBC 与事务 数据库初始化机制 阅读笔记 36
数据库·spring boot·笔记