Spring的三级缓存
斗胆写一篇技术博客,记录今天学习的三级缓存解决循环依赖问题,写的错误的和不好的地方请大家见谅(((φ(◎ロ◎;)φ)))
三级缓存的概念
1. 第一级缓存(Singleton Objects):
- 存放已经完全初始化好的单例bean.当一个bean被完全创建并初始化后,它会被存储在这里.
2. 第二级缓存(Early Singleton Objects):
- 存放原始的bean对象,即已经实例化但还没有完全初始化的bean.当Spring容器创建一个bean并注入了所有依赖项后,但还未调用afterPropertiesSet()方法或init-method时,bean会被存放在这里.
3. 第三级缓存(Singleton Factories):
- 存放ObjectFactory,即bean创建工厂(用于创建早期对象).当Spring容器创建bean的实例时,但还未进行属性填充(依赖注入)之前,会先存放一个bean工厂在第三级缓存中.
循环依赖解决过程详解:
- Bean A 的创建初始化:
- Spring容器开始创建Bean A.
- 实例化:容器首先实例化Bean A(new OperationA()),此时它是一个原始的Java对象,不包含任何Spring的代理或增强.
- 第三级缓存:这个原始对象被包装为一个ObjectFactory,并存入第三级缓存(SingletonFactories).
- Bean A 请求 Bean B:
- 在Bean A的属性填充过程中,Spring容器发现Bean A需要依赖Bean B.
- Bean B 创建:容器开始创建Bean B,同样先实例化Bean B.
- Bean B 请求 Bean A:
- 类似于Bean A,Bean B在属性填充时需要依赖Bean A.
- 早期引用:由于Bean A尚未完全初始化,Spring容器从第三级缓存中取出Bean A的ObjectFactory.
- 第二级缓存:调用ObjectFactory得到Bean A的早期引用(一个尚未填充属性的Bean A实例),并将其存入第二级缓存(EarlySingletonObjects).
- Bean B 依赖注入 Bean A:
- 将Bean A的早期引用注入到Bean B中.
- Bean B 初始化:Bean B完成属性填充,执行afterPropertiesSet或自定义的初始化方法,然后从第二级缓存移动到第一级缓存(SingletonObjects).
- Bean B 完成创建:
- Bean B现在是一个完全初始化的单例对象,可以从第一级缓存中获取.
- Bean A 依赖注入 Bean B:
- 回到Bean A的创建过程,Spring容器从第一级缓存中获取完全初始化的Bean B.
- Bean A 完成属性填充:
- Bean A的所有属性(包括注入的Bean B)都已填充完毕.
- Bean A 初始化:
- 执行Bean A的afterPropertiesSet或自定义的初始化方法.
- Bean A 完成创建:
- Bean A从第二级缓存移动到第一级缓存,现在是一个完全初始化的单例对象.
- Bean A 和 B 都可用:
- 至此,Bean A和Bean B都完全创建并初始化,可以被应用程序使用.
- 概念区分:
- 实例化对象:指的是Java的new操作创建的对象,此时对象尚未经过Spring容器的任何处理.
- 早期对象:指的是已经实例化但还未完全初始化的bean,它存在于第二级缓存中.
- 完全初始化对象:指的是已经完成所有属性填充和初始化方法调用的bean,存在于第一级缓存中.
- 对象工厂(ObjectFactory):是一个能够创建bean实例的工厂,存在于第三级缓存中,用于在循环依赖中提前暴露bean的早期引用.
- 实例工厂(Instance Factory):通常指的是Spring容器内部用于创建bean实例的逻辑,这里可以认为是ObjectFactory的具体实现.
通过以上方式,就通过引入三级缓存,解决了循环依赖的问题,在上述流程执行完之后,ServiceA和ServiceB都被成功的完成了实例化和初始化.
欢迎大佬批评指正!
评论
问答助学
相关内容
0个评论
全部评论
点击登录,快来和大家讨论吧~
表情
图片
暂无评论
内容推荐
二
2
Day 13✅ 今天做了:6007复习:动态规划、最短路径、马尔可夫决策。⏰ 明天计划:1、6007复习、练习题、期中考2、5489作业3、学一下把ds接入qq4、优化马里奥项目,参考别人的参数进行优化
3
1. 什么是流式对话?WebSocket 和流式对话有什么区别?2.在 RAG 中 Embedding 究竟是什么?如何选择和评估一个 Embedding 模型?3.什么是AOP?谈谈你对AOP的理解?4.线程池中 submit() 和 execute() 方法有什么区别?5.如何合理分配线程池大小?
2
day5✅️:SpringBoot进度一点点,项目进度11%以上⏰️:加快SpringBoot的进度📚:没有web基础,学着好吃力啊但没办法必须快一点;Maven的反复配置和报错,插件的选择······我真的改到吐血了!凌晨2点16分,项目终于不报错了没有红色下划线了·······我深刻的发现,真正困难的、拖慢学习进度的,其实并不是知识和技术有多难学,而是准备阶段太痛苦了,任何的前提配置的独立探
5
一.今天学了事务怎么在业务中使用事务@transaction注解@propagation注解二.明天目标hot100 两道三.今日感悟最近对学习提不起兴趣,先爽几天👿👿👿这是今天上课无聊看的面试题
2
作者分享
HTTP和HTTPS差别之一
2
初探多模态RAG
5
好好好 三天被老登安排的明明白白 麻了
但今天还是抽空复习了Redis!为自己点赞!
1
记录一下 15:31完成场景题复习 感觉忘掉的10%不到 可喜可贺 下了大功夫终究还是会有收获的
MQ启动
1
记录一下 10:28 完成数据库复习 也就那点东西
数据库范式与反范式 更新事务是怎么实现的 bufferpool 四个隔离级别,如何解决脏读幻读不可重复读 MVCC原理
索引 联合索引 索引下推 索引覆盖 索引失效原因 索引的作用
锁 行级锁 表级锁 意向锁 字典锁用来保证表结构不被改变 auto-inc锁确保主键自增
自增主键用完了怎么办
orderby实现原理 filesort 全字段排序 row_id
数据库的主从复制 两阶段提交 组复制 binlog undolog redolog分别什么作用
InnoDB的数据结构 为什么用B+树不用跳表 redis为什么用跳表不用B+树
逻辑都蛮清晰的,真真切切感受到老前辈们的奇思妙想
技术性的八股还是比较容易记住的,常看常新。用的时候一些犄角旮旯奇奇怪怪的东西就比较难记了
加油吧!半小时后开组会 也算是完成了上午的任务 中午算法继续 下午先场景题 再mq 晚上redis
3
