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就没有提前代理的问题呢?

相关推荐
二哈赛车手7 小时前
新人笔记---ApiFox的一些常见使用出错
java·笔记·spring
栗子~~7 小时前
JAVA - 二层缓存设计(本地缓冲+redis缓冲+广播所有本地缓冲失效) demo
java·redis·缓存
YDS8298 小时前
DeepSeek RAG&MCP + Agent智能体项目 —— RAG知识库的搭建和接口实现
java·ai·springboot·agent·rag·deepseek
星星也在雾里8 小时前
PgBouncer 解决 PostgreSQL 连接数超限 + 可视化监控
数据库·postgresql
未若君雅裁9 小时前
MyBatis 一级缓存、二级缓存与清理机制
java·缓存·mybatis
AI人工智能+电脑小能手9 小时前
【大白话说Java面试题 第65题】【JVM篇】第25题:谈谈对 OOM 的认识
java·开发语言·jvm
阿维的博客日记10 小时前
Nacos 为什么能让配置动态生效?(涉及 @RefreshScope 注解)
java·spring
雨辰AI10 小时前
SpringBoot3 + 人大金仓读写分离 + 分库分表 + 集群高可用 全栈实战
java·数据库·mysql·政务
长城202410 小时前
关于MySql的ONLY_FULL_GROUP_BY问题
数据库·mysql·聚合列
常常有10 小时前
MySQL 底层执行原理:输入SQL语句到两阶段提交
数据库·sql·mysql