说说你对Spring三级缓存的理解

news2024/11/18 20:26:44

这个问题或者换个问法:Spring是如何解决循环依赖的?答案即是Spring的三级缓存

什么是循环依赖?

简单说,就是A对象依赖B对象,B对象⼜依赖A对象,类似的代码如下:
 

其他还有很多种⽅式,如A依赖B,B依赖C,C依赖A,或是A依赖A⾃⼰,只要产⽣了依赖关系的闭环,即造成了循环依赖。

那么,循环依赖会引发什么问题呢?理解这个问题先得理解Bean的⽣命周期

Bean的⽣命周期

1. 启动容器:加载Bean
2. 实例化Bean对象
3. 依赖注⼊:装配Bean的属性
4. 初始化Bean:执⾏aware接⼝⽅法、预初始化⽅法、初始化⽅法、后初始化⽅法
5. 关闭容器:销毁Bean


在以上第四个步骤执⾏完毕,才算⼀个初始化完成的Bean,也即Spring容器中完整的Bean对象。



 循环依赖的问题

Spring容器保存Bean的⽅式,是采取缓存的⽅式:使⽤ Map<String, Object> 的结构,key为
Bean的名称,value为Bean对象。需要使⽤时直接从缓存获取
假如A、B互相依赖(循环依赖):
1. 容器中没有A对象,实例化A对象
2. 装配A中的B对象,发现B在容器中没有,需要先实例化B
3. 实例化B对象
4. 装配B中的A对象,发现A在容器中没有,需要先实例化A
5. 重复第⼀个步骤
这就套娃了, 你猜是先 StackOverflow 还是 OutOfMemory ?
Spring怕你不好猜,就先抛出了 BeanCurrentlyInCreationException

  • Bean会依赖某些注⼊的Bean来完成初始化⼯作
  • 由于Spring⽀持构造⽅法注⼊,属性/Setter注⼊的⽅式,所以不能简单的先把所有对象全部实例化,放到缓存中,再全部执⾏初始化。原因很简单,此时所有对象的引⽤都可以获取到,但属性都是null,执⾏初始化甚⾄构造⽅法都可能出现空指针异常。

那么我们说Spring能解决循环依赖,也不是所有的情况都可以解决,只有以下情况才⽀持
 

Spring⽀持的循环依赖
在Spring容器中注册循环依赖的Bean,必须是单例模式,且依赖注⼊的⽅式为属性注⼊。
原型模式及构造⽅法注⼊的⽅式,不⽀持循环依赖。以下为说明:

  • 原型模式(prototype)的Bean:原因很好理解,创建新的A时,发现要注⼊原型字段B,⼜创建新的B发现要注⼊原型字段A...还是典型的套娃⾏为...
  • 基于构造器的循环依赖,就更不⽤说了,官⽅⽂档都摊牌了,你想让构造器注⼊⽀持循环依赖,是不存在的,不如把代码改了

那么默认单例的属性注⼊场景,Spring是如何⽀持循环依赖的?

Spring解决循环依赖

Spring是使⽤三级缓存的机制来解决循环依赖问题,以下为三级缓存的定义:



 

 三级缓存的源码⻅ DefaultSingletonBeanRegistry :

以下是部分说明:

  • 三级缓存singletonFactories中保存的是ObjectFactory对象(Bean⼯⼚),其中包含了BeanName,Bean对象,RootBeanDefinition,该⼯⼚可以⽣成Bean对象。
  • 由于Bean可能被代理,此时注⼊到其他Bean属性中的也应该是代理Bean。 

单例模式的A、B循环依赖执⾏流程如下:


 

为什么要使⽤三级缓存?

依照以上三级缓存的流程,其实使⽤⼆级缓存也能满⾜循环依赖的注⼊:

  • 普通的IoC容器使⽤⼀级缓存即可,但⽆法解决循环依赖问题。
  • 解决循环依赖问题:使⽤⼆级缓存即可。⼀级缓存保存完整Bean,⼆级缓存保存提前曝光的不完整的Bean。
  • 需要AOP代理Bean时,有两种实现思路:(1)再加⼀级缓存(2)只使⽤⼆级缓存,其中⼆级缓存保存Bean的代理对象,代理对象中引⽤不完整的原始对象即可。
  • Spring使⽤三级缓存保存ObjectFactory即Bean⼯⼚,在代码的层次设计及扩展性上都会更好。ObjectFactory内部可以根据 SmartInstantiationAwareBeanPostProcessor 这样的后置处理器获取提前曝光的对象

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/159910.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

内核解读之内存管理(12)进程虚拟内存管理 vm_area_struct 与反向映射

在32位的系统上&#xff0c;线性地址空间可达到4GB&#xff0c;这4GB一般按照3:1的比例进行分配&#xff0c;也就是说用户进程享有前3GB线性地址空间&#xff0c;而内核独享最后1GB线性地址空间。由于虚拟内存的引入&#xff0c;每个进程都可拥有3GB的虚拟内存&#xff0c;并且…

靶机测试ReconForce笔记

靶机地址https://www.vulnhub.com/entry/hacknos-reconforce,416/靶机测试信息收集nmap扫描端口nmap扫描结果└─$ nmap -sC -sV 192.168.1.100 -oA hack …

结合NWR,让Paxos拥有的动态的Quorum,以及在Klein中的实践

Paxos Quorum面临的困境在原生的Basic-Paxos或者Multi-Paxos中&#xff0c;Quorum的数量要求的是多数派&#xff0c;例如&#xff1a;一个5成员组成的Paxos集群&#xff0c;Prepare和Accept阶段需要获得3个Acceptor的支持。Quorum3的条件&#xff0c;在原生的Paxos中是硬性条件…

NTP服务器(GPS北斗授时服务器)的市场需求及性能分析

NTP服务器&#xff08;GPS北斗授时服务器&#xff09;的市场需求及性能分析 NTP服务器&#xff08;GPS北斗授时服务器&#xff09;的市场需求及性能分析 目前国内NTP时间服务器时间精度已达到毫秒级&#xff0c;能够满足各个行业对时间同步运转的要求&#xff1b;有些企业需要…

QtitanComponents Solution 2022.4.0 Crack

2022-12-29 开始开发基于Adobe XD文件的Qt样式创建工具 包括&#xff1a; QtitanDataGrid QtitanRibbon QtitanNavigationDesignUI QtitanChart QtitanDocking QtitanFastInfoset 不要问我源码&#xff0c;没有&#xff0c;&#xff0c;&#xff0c;&#xff0c;&#x…

Spring Boot 加载外部配置文件

Spring Boot 允许你从外部加载配置&#xff0c;这样的话&#xff0c;就可以在不同的环境中使用相同的代码。支持的外部配置源包括&#xff1a;Java属性文件、YAML文件、环境变量、命令行参数。用Value注解可以将属性值直接注入到beans中。命令行参数以 -- 开头配置文件加载的顺…

数据结构学习

数据结构 单值二叉树 如果二叉树每个节点都具有相同的值&#xff0c;那么该二叉树就是单值二叉树。只有给定的树是单值二叉树时&#xff0c;才返回 true&#xff1b;否则返回 false。 类似上述图中&#xff0c;所有结点都为1&#xff0c;那么返回true&#xff0c;只要有一个结…

QT智能停车管理系统

智能停车管理系统 密级Confidentiality level 需求说明书 内部公开 产品版本Product version Total pages 共 7页 V100R001 智能停车管理系统项目 需求规格说明书 拟制人&#xff1a; 孙献 时间&#xff1a; 2023.1.7 评审人&#xff1a; 覃丽红 时间&#xff1a;…

Java项目:网上水果超市商城设计和实现(java+SSM+springboot+redis)

源码获取&#xff1a;本博客首页 "资源" 处下载&#xff01; 主要技术实现&#xff1a;spring、 springmvc、 redis、 springboot、 mybatis 、session、 jquery 、 md5 、bootstarp.js tomcat、、拦截器等。 主要功能实现&#xff1a; 前端&#xff1a;登录、注册…

Instagram 账号被封如何申诉拿回账号?ins账号解封经验分享

不知道各位在玩转海外社媒平台时有没有遇到过Instagram账号异常的情况&#xff0c;比如会出现账号受限、帖子发不出去、账号被封号等情况? Instagram账号如果被封不用马上弃用&#xff0c;我们可以先尝试一下申诉&#xff0c;看看能不能把账号解封。所以今天东哥将会出一篇Ins…

94、【树与二叉树】leetcode ——110. 平衡二叉树(C++版本)

题目描述 原题链接&#xff1a;110. 平衡二叉树 解题思路 一、后序遍历&#xff08;自底向上&#xff09; 在这里要和 90、【树与二叉树】leetcode ——104. 二叉树的最大深度&#xff1a;层次遍历DFS子问题分解&#xff08;C版本&#xff09; 这个作比较。 深度&#xff0…

黑马前端毕业生面试攻略

为不断提升学生就业质量&#xff0c;黑马上海校区率先实施“新就业模式”&#xff0c;采用精细化管理&#xff0c;将就业动作拆解到了课程周期内的各个阶段&#xff0c;提前制定和铺垫课程阶段对应的就业动作目标和重点&#xff0c;并严格落实把控&#xff0c;更高效地完成学生…

JavaScript Event对象

文章目录JavaScript Event对象概述Event对象属性方法event对象常用属性typekeyCode获取Event对象兼容代码获取事件的目标对象target属性和currentTarget属性JavaScript Event对象 概述 事件在浏览器中是以Event对象的形式存在的&#xff0c;每触发一个事件&#xff0c;就会产…

【魅力开源】第2集:三个人每人一个想法会发生什么故事?关于Odoo的江湖

文章目录一. 关于权限控制&#xff1a;组织、角色、人员权限的说明二. 关于快速批量功能&#xff1a;有一些事情可以交给电脑来做三. 关于可以拖拉拽应用&#xff1a;技术模块3.1 可配置的MVC3.2 简单开发下附件模块也可用来作为企业的知识沉淀3.3 多语言支持&#xff1a;对于跨…

第五届“泰迪杯”数据分析技能赛 经验代码分享

第五届“泰迪杯”数据分析技能赛 经验/代码分享 品牌&#xff1a;“泰迪杯”数据分析技能赛 组织单位&#xff1a;泰迪杯数据分析技能赛组织委员会、广东泰迪智能科技股份有限公司、广东省工业与应用数学学会、人民邮电出版社、北京泰迪云智信息技术研究院、网宿科技股份有限…

内存管理详解

目录 一、C/C中内存分布 二、C语言的内存管理方式 三、C的内存管理方式 3.1 new/delete操作内置类型 3.2 new/delete操作自定义类型 3.3 operator new()和operator delete()函数 3.4 重载operator new()和operator delete() 四、new、delete的实现原理 4.1 内置类型 …

(02)Cartographer源码无死角解析-(50) 2D点云扫描匹配→相关性暴力匹配2:RealTimeCorrelativeScanMatcher2D

讲解关于slam一系列文章汇总链接:史上最全slam从零开始&#xff0c;针对于本栏目讲解(02)Cartographer源码无死角解析-链接如下: (02)Cartographer源码无死角解析- (00)目录_最新无死角讲解&#xff1a;https://blog.csdn.net/weixin_43013761/article/details/127350885 文末…

【论文速递】TPAMI2022 - 小样本分割的整体原型激活

【论文速递】TPAMI2022 - 小样本分割的整体原型激活 【论文原文】&#xff1a;Holistic Prototype Activation for Few-Shot Segmentation 获取地址&#xff1a;https://ieeexplore.ieee.org/document/9839487 CSDN下载&#xff1a;https://download.csdn.net/download/qq_36…

三十、RabbitMQ(1)

&#x1f33b;&#x1f33b; 目录一、 关于中间件的概述二、基于消息中间件的分布式系统的架构2.1 消息中间件应用的场景2.2 常见的消息中间件2.3 消息中间件的本质及设计2.4 消息中间件的核心组成部分2.5 小总结三、消息队列协议3.1 什么是协议3.2 网络协议的三要素3.3 AMQP 协…

JAVA 23种设计模式示例

目录 一.单例模式 二.工厂方法模式 三.抽象工厂模式 四.建造者模式 五.原型模式 六.享元模式 七.门面模式 八.适配器模式 九.装饰者模式 十.策略模式 十一.模板方法模式 十二.观察者模式 十三.责任链模式 十四.代理模式 十五.桥接模式 十六.组合模式 十七.命令…