当前位置: 首页 > news >正文

Spring解决循环依赖

Spring框架为了解决循环依赖问题,设计了一套三级缓存机制:

  • 一级缓存singletonObjects:这个是最常规的缓存,用于存放完成初始化好的bean,如果某个bean已经在这个缓存了直接返回。
  • 二级缓存earlySigletonObjects:这个用于存放早期暴露出来的bean,就是那些创建出来还没有初始化好的bean,这样做的目的就是为了bean创建过程中能提前暴露出来,方便解决循环依赖的问题。
  • 三级缓存 singletonFactories:这个缓存存放的是bean的工厂对象,这个工厂对象负责bean的实例,当一个bean创建时,它的工厂对象会被放入缓存中。

Spring解决循环依赖

三级缓存

  • singletonObjects:用于存放完全初始化好的 bean,从该缓存中取出的 bean 可以直接使用

  • earlySingletonObjects:提前曝光的单例对象的cache,存放原始的 bean 对象(尚未填充属性),用于解决循环依赖

  • singletonFactories:单例对象工厂的cache,存放 bean 工厂对象,用于解决循环依赖

整体流程
  1. 首先A完成初始化第一步先将自己提前曝光出来(通过ObjectFactory将自己提前曝光出来),在初始化的时候,发现自己需要依赖B,就开始尝试get(B),这时候发现B还没有创建;

  2. B走创建流程,在B初始化的时候依赖C,C还没有创建出来;

  3. C开始初始化,在C初始化的时候发现自己依赖A,于是尝试get(A),这时候由于A已经添加到缓存中了(一般都是添加到三级缓存中singletonFactory),通过ObjectFactory提前曝光,所以可以通过ObjectFactory#getObject()获取到A对象。C拿着A对象后顺利初始化,然后自己添加到一级缓存中;

  4. 回到B,B也拿到C对象,完成初始化,A可以顺利拿到B,这里整个链路已经完成初始化过程了。

关键字:三级缓存,提前曝光

再来一个例子

假设现在有两个bean,一个A,一个B;

Spring容器开始创建A对象,会先去一级缓存中查看是否有BeanA的实例,如果没有就会创建一个A的实例,并将其工厂对象放入三级缓存中,然后BeanA 的创建因为需要注入B而被挂起,Spring开始创建BeanB对象。

BeanB同样回去一级缓存中查找是否存在B实例,由于还没有创建,Spring会将bean B的半成品放入二级缓存,继续创建买这个B需要依赖A,由于A的工厂对象已经放在三级缓存中了,spring可以直接获取三级对象中的beanA的工厂对象,通过它来创建beanA的实例。

这样,即使两个 beans 相互依赖,Spring 也能够通过三级缓存机制成功地创建它们,解决了循环依赖的问题。

仅有二级缓存无法解决涉及AOP代理的循环依赖问题。

为什么二级缓存不可以

二级缓存earlySingletonObjects用于存储半成品的Bean实例,即那些已经被实例化但尚未完成初始化(如属性填充和方法调用)的Bean。这个缓存允许Spring在Bean的创建过程中就能提前暴露出来,以便于解决循环依赖的问题。然而,如果只有二级缓存,当涉及到AOP代理时,问题就来了。

AOP代理的生成是在Bean的初始化阶段完成的,这意味着在Bean的所有属性都被设置之后。如果一个Bean需要被代理,那么在代理之前,Spring会尽量从缓存中获取到原始的Bean实例,以避免在代理过程中出现循环引用的问题。但是,如果只有二级缓存,那么在Bean初始化之前,我们无法从缓存中获取到代理对象,因为二级缓存中存储的是尚未初始化的Bean实例,而不是代理对象。

例子

假设有两个Bean,A和B,它们相互依赖,并且A需要被AOP代理。在Spring的创建过程中,首先会创建A的实例并将其放入二级缓存中。然后,当尝试创建B并注入A时,会发现A还没有完成初始化,因此无法生成A的代理对象。这样就会导致循环依赖的问题无法被解决。

而三级缓存中的singletonFactories存储的是Bean的工厂对象,可以在Bean初始化之前就生成代理对象,并将其放入一级缓存singletonObjects中。这样,即使Bean之间存在循环依赖,Spring也能够通过三级缓存机制成功地创建它们,解决了循环依赖的问题。

总的来说,三级缓存机制是Spring为了在保持设计原则的同时,解决循环依赖和AOP代理的问题而设计的。二级缓存虽然可以解决部分循环依赖的问题,但在面对AOP代理时就显得力不从心了。因此,Spring需要三级缓存来确保在复杂情况下依然能够正常工作。

相关文章:

Spring解决循环依赖

Spring框架为了解决循环依赖问题,设计了一套三级缓存机制: 一级缓存singletonObjects:这个是最常规的缓存,用于存放完成初始化好的bean,如果某个bean已经在这个缓存了直接返回。二级缓存earlySigletonObjects:这个用于存放早期暴…...

RUST运算符重载

在 Rust 中,可以使用特征(traits)来实现运算符重载。运算符重载是通过实现相应的运算符特征(如 Add、Sub、Mul 等)来完成的。这些特征定义在 std::ops 模块中。下面是一个简单的示例,展示如何为一个自定义结…...

描述一下 Array.forEach() 循环和 Array.map() 方法之间的主要区别

Array.forEach() 和 Array.map() 都是 JavaScript 数组中常用的方法,但它们之间有一些重要的区别: 返回值:forEach():没有返回值,它只是对数组中的每个元素执行提供的函数。map():返回一个新的数组,其元素是通过对原数组的每个元素执行提供的函数后的结…...

在GEE中显示矢量或栅格数据的边界(包含样式设计)

需要保证最后显示的数据是一个 FeatureCollection 对象。 如果数据是一个 Geometry 或 Image,我们也可以使用 style 方法来设置样式并将其添加到地图上。以下是针对不同类型对象的处理方式: 1 Geometry对象 如果 table 是一个 Geometry 对象&#xff…...

django使用fetch上传文件

在上一篇文章中,我包装了fetch方法,使其携带cookie。但是之前fetch传递的是json数据,现在有了一个上传文件的需求,因此需要进行修改: const sendRequest (url, method, data) > {const csrftoken Cookies.get(cs…...

linux安装docker步骤

步骤1 脚本自动安装 curl -fsSL https://get.docker.com -o get-docker.sh sudo sh get-docker.sh 步骤2 启动Docker服务: sudo systemctl start docker 步骤3 验证Docker是否正确安装并运行一个容器: sudo docker run hello-world 安装正确,则可拉取镜像&am…...

Unity DOTS技术(一)简介

文章目录 一.概述二.将会介绍的内容三.DOTS技术与传统方式的不同传统问题DOTS技术 四.插件安装 一.概述 传统的游戏开发中,如果有成千上万的物体在场景中运动,那么你一定会认为是疯了.但有了Dost技术这一些都将变成可能.如图场景中有10000个物体在同时运动,帧率即能保持在60Fp…...

深度解读ChatGPT基本原理

一、基本原理 ChatGPT是一个基于深度学习的自然语言生成模型,使用了类似于GPT(Generative Pre-trained Transformer)的架构。GPT是由OpenAI开发的一种语言模型,能够生成与输入文本相关的连续性文本。 ChatGPT的基本原理是先使用…...

python实现——分类类型数据挖掘任务(图形识别分类任务)

分类类型数据挖掘任务 基于卷积神经网络(CNN)的岩石图像分类。有一岩石图片数据集,共300张岩石图片,图片尺寸224x224。岩石种类有砾岩(Conglomerate)、安山岩(Andesite)、花岗岩&am…...

【安卓跨进程通信IPC】-- Binder

目录 BinderBinder是什么?进程空间分配进程隔离Binder跨进程通信机制模型优点AIDL常见面试题 Binder 夯实基础之超详解Android Binder的工作方式与原理以及aidl示例代码 比较详细的介绍:Android跨进程通信:图文详解 Binder机制 原理 操作系统…...

大数据之Schedule调度错误(一)

当我们在利用ooize发起整个任务的调度过程中,如果多个调度任务同时运行并且多个调度任务操作了相同的表,那么就会出现如下的错误关系: Invalid path hdfs://iZh5w01l7f8lnog055cpXXX:8000/user/admin/xxx: No files matching path hdfs://iZh5w01l7f8lnog055cpXXX:8000/user/ad…...

DiffIR论文阅读笔记

ICCV2023的一篇用diffusion模型做Image Restoration的论文,一作是清华的教授,还在NIPS2023上一作发表了Hierarchical Integration Diffusion Model for Realistic Image Deblurring,作者里甚至有Luc Van Gool大佬。模型分三个部分&#xff0c…...

prometheus+alertmanager+webhook钉钉机器人告警

版本:centos7.9 python3.9.5 alertmanager0.25.0 prometheus2.46.0 安装alertmanager prometheus 配置webhook # 解压: tar -xvf alertmanager-0.25.0.linux-amd64.tar.gz tar -xvf prometheus-2.46.0.linux-amd64.tar.gz mv alertmanager-0.25.0.linu…...

ctfshow 年CTF web

除夕 Notice: Undefined index: year in /var/www/html/index.php on line 16 <?phpinclude "flag.php";$year $_GET[year];if($year2022 && $year1!2023){echo $flag; }else{highlight_file(__FILE__); } 弱比较绕过很简单&#xff0c;连函数都没有直…...

原型链、闭包、手写一个闭包函数、 闭包有哪些优缺点、原型链继承

什么是原型链&#xff1f; 原型链是一种查找规则 为对象成员查找机制提供一个方向 因为构造函数的 prototype 和其实例的 __ proto __ 都是指向原型对象的 所以可以通过__proto__ 查找当前的原型对象有没有该属性, 没有就找原型的原型, 依次类推一直找到Object( null ) 为…...

linux中SSH_ASKPASS全局变量的作用

在工作中遇到一段代码&#xff0c;通过SSH_ASKPASS全局变量实现了ssh登录远程IP时的密码输入&#xff0c;chatgpt搜索了一下&#xff0c;其解释大致如下所示&#xff1a; SSH_ASKPASS 是一个环境变量&#xff0c;它在 SSH 客户端需要用户输入密码时起作用。当 SSH 客户端检测到…...

9 -力扣高频 SQL 50 题(基础版)

9 - 上升的温度 -- 找出与之前&#xff08;昨天的&#xff09;日期相比温度更高的所有日期的 id -- DATEDIFF(2007-12-31,2007-12-30); # 1 -- DATEDIFF(2010-12-30,2010-12-31); # -1select w1.id from Weather w1, Weather w2 wheredatediff(w1.recordDate,w2.recordDat…...

TCP的重传机制

TCP 是一个可靠的传输协议&#xff0c;解决了IP层的丢包、乱序、重复等问题。这其中&#xff0c;TCP的重传机制起到重要的作用。 序列号和确认号 之前我们在讲解TCP三次握手时&#xff0c;提到过TCP包头结构&#xff0c;其中有序列号和确认号&#xff0c; 而TCP 实现可靠传输…...

pg 数据库,获取时间字段值的具体小时,赋值给其他字段

目录 1 问题2 实现 1 问题 pg 数据库&#xff0c;有一个表&#xff0c;其中有2个字段 一个是时间字段obstime &#xff0c;一个是时次ltime字段&#xff0c;int 类型&#xff0c;现在这个表里面是obstime 里面有数据&#xff0c;ltime字段 没有数据&#xff0c;现在就是批量获…...

做视频号小店什么类目最容易爆单?其实,弄懂这三点就会选品了

大家好&#xff0c;我是电商花花。 我们做视频号小店做什么类目最容易爆单&#xff1f; 其实任何类目都有属于自己的受众人群和客户&#xff0c;都非常容易爆单&#xff0c;我们想要爆单&#xff0c;就要选对类目&#xff0c;选对产品。 视频号上所有的类目基本上可以分为标…...

10个HTTPie CLI高级功能实战技巧:从入门到精通API调试

10个HTTPie CLI高级功能实战技巧&#xff1a;从入门到精通API调试 【免费下载链接】cli &#x1f967; HTTPie CLI — modern, user-friendly command-line HTTP client for the API era. JSON support, colors, sessions, downloads, plugins & more. 项目地址: https:/…...

杰理之关机DAC未进入高阻【篇】

memset(JL_ADDA, 0x0, sizeof(JL_ADDA_TypeDef)); SFR(JL_ADDA->DAA_CON2, 15, 1, 1); SFR(JL_ADDA->DAA_CON2, 5, 1, 1);...

百川2-13B-4bits量化版模型蒸馏:为OpenClaw定制更小尺寸专用模型

百川2-13B-4bits量化版模型蒸馏&#xff1a;为OpenClaw定制更小尺寸专用模型 1. 为什么需要为OpenClaw定制专用模型 去年冬天&#xff0c;当我第一次尝试在树莓派上部署OpenClaw时&#xff0c;遇到了一个尴尬的问题——即使是最轻量级的开源模型&#xff0c;也会让这个小家伙…...

OpenClaw爆火!Token是什么?一文搞懂这个AI核心概念!

随着龙虾OpenClaw这几天的爆火&#xff0c;token也成了高频词。“养龙虾”并不是免费的&#xff0c;OpenClaw需要接入大模型&#xff0c;平时各种操作都要消耗token 最近网上还有一个很好笑的梗&#xff1a;用自己的脑子思考不会消耗token那么token究竟是什么&#xff1f;我在O…...

机器人双目视觉定位系统设计与开发

机器人双目视觉定位系统设计与开发 摘要 双目视觉定位技术是机器人感知环境、实现自主导航和精准操作的核心技术之一。本系统基于双目立体视觉原理,利用Matlab平台完成了从相机标定、图像采集、立体匹配到三维坐标解算的完整流程。系统采用张正友标定法获取相机内外参数,通…...

CVPR 2024人脸黑科技:3D头像重建如何用单张自拍搞定?附开源项目推荐

CVPR 2024单图3D头像重建技术实战&#xff1a;从算法原理到开源工具落地 当你在社交媒体上传自拍时&#xff0c;是否想过这张平面照片能瞬间转化为可360度旋转的数字化身&#xff1f;CVPR 2024最新研究成果正在让这个想象成为现实——无需专业设备&#xff0c;仅用普通手机拍摄…...

避坑指南:R语言中XGBoost回归建模的5个常见错误与SHAP分析的正确姿势

避坑指南&#xff1a;R语言中XGBoost回归建模的5个常见错误与SHAP分析的正确姿势 在数据科学领域&#xff0c;XGBoost因其出色的预测性能而广受欢迎&#xff0c;而SHAP&#xff08;Shapley Additive Explanations&#xff09;则为模型解释提供了强大的数学基础。然而&#xff0…...

解锁Visual Studio中的图标编辑:.CUR文件的编辑指南

在软件开发中,图标是用户界面设计的重要组成部分。它们不仅能增强应用程序的美观度,还能提供直观的操作指引。然而,对于那些不熟悉Visual Studio环境的开发者来说,编辑图标文件可能遇到一些障碍。本文将详细介绍如何在Visual Studio中编辑.CUR文件,以及为什么默认情况下这…...

颠覆视频剪辑:JianYingApi让自动化剪辑效率提升80%

颠覆视频剪辑&#xff1a;JianYingApi让自动化剪辑效率提升80% 【免费下载链接】JianYingApi Third Party JianYing Api. 第三方剪映Api 项目地址: https://gitcode.com/gh_mirrors/ji/JianYingApi 在短视频内容爆发的时代&#xff0c;视频创作者面临着三重核心痛点&…...

ai赋能自动化测试:用快马平台让openclaw在win10上实现智能脚本生成与修复

最近在尝试用OpenClaw做自动化测试时&#xff0c;发现传统脚本编写方式效率太低&#xff0c;于是研究了下如何结合AI提升开发体验。在InsCode(快马)平台实践后发现&#xff0c;AI辅助能让测试脚本真正"活"起来。分享几个实用功能点&#xff1a; 智能元素定位的救场能…...