浅谈Spring三级缓存

目录

1.什么是循环依赖?

2.三种常见形式

3.图解

4.避免出现循环依赖的方式

5.补充


最近一直在面试,上周遇到这个问题,因为之前其实梳理过这个问题,但是因为时间过去很久,一些细节给忽略掉了,今天正好找到了之前画的示意图,针对Spring的循环依赖问题的解决方案,再尝试自己去理解下,可能不是很周全,如有错的地方,还望指正。

开门见山,就不再赘述什么是循环依赖,简单提一下就是A服务依赖B服务,同时B服务也依赖A服务,当然也有三者之间的闭环依赖,总之就是依赖之间的闭环。

1.什么是循环依赖?

例如:两个或多个 Bean 互相持有对方的引用,形成依赖闭环:

java 复制代码
@Component
public class BeanA {
    @Autowired
    private BeanB beanB;
}

@Component
public class BeanB {
    @Autowired
    private BeanA beanA;
}

2.三种常见形式

注入方式 是否能被 Spring 解决 说明
Setter/Field 注入(单例) ✅ 能解决 最常见场景,也是三级缓存的主战场
构造器注入 ❌ 无法解决 实例化阶段就必须拿到完整对象,无机会提前暴露
多例 Bean ❌ 无法解决 不缓存 Bean,每次 getBean 都新建,会无限递归

3.图解

4.避免出现循环依赖的方式

  • 拆分公共逻辑到新类 C,让 A 和 B 都依赖 C,而不是互相依赖
  • 用依赖倒置原则,把高层模块的依赖抽象出来
  • 把构造器注入改成 @Autowired 字段 /setter 注入
  • 延迟注入:用 @Lazy 注解,注入时不立即初始化 Bean

5.补充

面试的过程中,提到一个为什么不使用二级缓存,为什么是三级缓存,解决了什么问题,当时说实话,这块确实忘了,今天再看才回忆起来,其实是因为要解决的是AOP的代理,因为二级缓存确实是可以解决了循环依赖,但是考虑到如果存在AOP代理的话,只用二级缓存是可能出现原始对象和代理对象不统一的,什么意思呢?注入的是a服务的半成品,此时AOP都是不生效的,但是最后生成了完整的a服务bean的时候是拥有AOP的代理对象的,所以会导致两者不一致。

以上是我个人的见解,欢迎交流留言!

相关推荐
狼爷2 小时前
Rust/Go/Java/Python/PHP 大比拼:负载下后端框架到底差多少?
java·后端·编程语言
念何架构之路2 小时前
zap扩展生态与总结
java·前端·数据库
第七页独白2 小时前
汽车零件厂如何通过 QMS 真正落地 IATF 16949——QMS软件系统:品质检验-内审稽核-8d客诉管理:全星质量管理软件系统
java·前端·数据库
QCoding3 小时前
Spring AI Alibaba Graph实战:从ReAct Agent到Workflow,企业AI复杂流程该如何编排?
java·人工智能
用户094248568033 小时前
第25章:Java虚拟线程(Project Loom)实战与调度协作
java·jvm
砚底藏山河3 小时前
量化实战:截面因子有效性检验(IC 分析与分层回测)
java·python·金融·maven
wuminyu3 小时前
ForkJoinPool内部WorkQueue的Lock-Free数组操作以及并发任务窃取原理剖析
java·linux·c语言·jvm·c++
Elastic 中国社区官方博客3 小时前
使用 Lucene 搜索你的 Bean — 索引
java·大数据·数据库·elasticsearch·搜索引擎·全文检索·lucene
code2cat3 小时前
Java进阶篇之AtomicMarkableReference:引用还在,标记已经改变
java·开发语言·cas·并发编程·逻辑删除
她说彩礼65万3 小时前
C语言 堆区和栈区
java·linux·c语言