spring ioc的循环依赖问题

news2024/11/16 0:56:22

spring ioc的循环依赖问题

  • 什么是循环依赖
  • spring中循环依赖的场景
    • 通过构造函数注入时的循环依赖
    • 通过setter或@Autowired注入时的循环依赖
  • 循环依赖的处理机制
    • 原型bean循环依赖
    • 单例bean通过构造函数注入循环依赖
    • 单例bean通过setter或者@Autowired注入的循环依赖
      • 三级缓存
      • 对象的创建分为两步
      • 循环依赖的处理机制
  • 回顾bean的创建流程如何处理循环依赖
    • AbstractBeanFactory#doGetBean
    • AbstractAutowireCapableBeanFactory#createBean(String, RootBeanDefinition, Object[])
    • AbstractAutowireCapableBeanFactory#doCreateBean
      • DefaultSingletonBeanRegistry#addSingletonFactory
      • AbstractAutowireCapableBeanFactory#populateBean
    • AbstractAutowireCapableBeanFactory#applyPropertyValues
    • BeanDefinitionValueResolver#resolveValueIfNecessary
    • BeanDefinitionValueResolver#resolveReference
    • AbstractBeanFactory#getBean(java.lang.String)
    • AbstractBeanFactory#doGetBean
    • DefaultSingletonBeanRegistry#getSingleton(java.lang.String)
    • DefaultSingletonBeanRegistry#getSingleton(java.lang.String, boolean)

什么是循环依赖

spring ioc的循环依赖通常是指bean与bean之间的相互依赖,
例如A持有对B的引用、B持有对A的引用,形成一个闭环,

在这里插入图片描述

相对于这种我们一眼可以看出来的相互引用,
实际引用中可能比这复杂、也隐蔽的多,
要隐蔽、复杂的多,
形成一个环形依赖。

spring中循环依赖的场景

通过构造函数注入时的循环依赖

通过setter或@Autowired注入时的循环依赖

其中,构造函数注入的循环依赖无法解决,只能抛出BeanCurrentlyCreationException异常,
在解决循环依赖时,spring采用的是提前暴露对象的方法。

spring的循环依赖基于Java的引用传递,
当获得对象的引用时,对象属性可以延后设置,
而通过构造器注入时,对象属性则必须在引用之前设置。

setter或@Autowired相当于是获得对象的引用。

循环依赖的处理机制

我们先来回顾一下bean的作用范围,
singleton:单例,spring默认的scope,容器中只存在一个对象;
prototype:原型,每次getBean都会返回一个新的对象;

单例模式bean的生命周期与容器相同,
原型模式bean,spring框架只负责创建,并不负责销毁。

原型bean循环依赖

无法解决,
对于原型模式的bean初始化过程中,
无论是通过构造器还是属性注入产生的循环依赖,spring都直接会抛出异常。

单例bean通过构造函数注入循环依赖

无法解决。

单例bean通过setter或者@Autowired注入的循环依赖

可以解决,

spring是通过三级缓存来解决循环依赖问题的。

三级缓存

一级缓存:单例池;
二级缓存:earlySingletonObjects;
三级缓存:singletonFactories。

对象的创建分为两步

1、实例化bean;
2、设置属性值。

循环依赖的处理机制

A和B互相依赖,

假如先去创建A,
A实例化后先把自己放入三级缓存,目的是为了提前暴露,
然后发现依赖B,
接着创建B,B依赖A,
B会去三级缓存中找A,使用并将A放入二级缓存,
B创建完后会把自己放入一级缓存,
A使用一级缓存中的B。

回顾bean的创建流程如何处理循环依赖

AbstractBeanFactory#doGetBean

在这里插入图片描述

这里,

	sharedInstance = getSingleton(beanName, () -> {
		try {
			return createBean(beanName, mbd, args);
		}
		catch (BeansException ex) {
			// Explicitly remove instance from singleton cache: It might have been put there
			// eagerly by the creation process, to allow for circular reference resolution.
			// Also remove any beans that received a temporary reference to the bean.
			destroySingleton(beanName);
			throw ex;
		}
	});

的lambda表达式就相当于传入了一个方法,

另外getSingleton会将最后创建好的对象放入单例池。

AbstractAutowireCapableBeanFactory#createBean(String, RootBeanDefinition, Object[])

在这里插入图片描述

AbstractAutowireCapableBeanFactory#doCreateBean

在这里插入图片描述

DefaultSingletonBeanRegistry#addSingletonFactory

放入三级缓存

在这里插入图片描述

AbstractAutowireCapableBeanFactory#populateBean

填充属性

在这里插入图片描述

AbstractAutowireCapableBeanFactory#applyPropertyValues

在这里插入图片描述

BeanDefinitionValueResolver#resolveValueIfNecessary

在这里插入图片描述

BeanDefinitionValueResolver#resolveReference

接下来这是获取依赖

在这里插入图片描述

AbstractBeanFactory#getBean(java.lang.String)

在这里插入图片描述

AbstractBeanFactory#doGetBean

在这里插入图片描述

DefaultSingletonBeanRegistry#getSingleton(java.lang.String)

在这里插入图片描述

DefaultSingletonBeanRegistry#getSingleton(java.lang.String, boolean)

在这里插入图片描述

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

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

相关文章

Metasploit 操作及内网 Pivot图文教程

目录 一、metasploit 简介 二、 基本使用 三、 使用 encoders 四、pivot 技术 一、metasploit 简介 Metasploit 是一款开源的安全漏洞检测工具,集成了丰富的渗透测试工具,深受安 全工作者喜爱。官方网站:www.metasploit.com 本案例将以图…

OS-调度

调度 多个程序在并发的情况下执行,最大化CPU利用率,同时要保证一定的公平性 调度的时机 五种情况: Running -> Waiting:例如等待I/ORunning -> Ready: interupt,计时器到时间了Running -> TerminatedWait…

我把Idea给改了,看看有没有你常用的功能,没有,你告诉我,我来改

改造的目标 时隔2个多月的研发,11月25日,终于把Idea插件BG-BOOM的1.1.0版本搞上线了,本次更新勇哥也是百忙之中挤时间,加班加点开发为粉丝,目的也主要是帮助大家提升开发效率,有更多摸鱼和内卷时间&#x…

[附源码]Python计算机毕业设计SSM晋中学院教室管理系统(程序+LW)

项目运行 环境配置: Jdk1.8 Tomcat7.0 Mysql HBuilderX(Webstorm也行) Eclispe(IntelliJ IDEA,Eclispe,MyEclispe,Sts都支持)。 项目技术: SSM mybatis Maven Vue 等等组成,B/S模式 M…

QT中怎么设置定时器/周期任务/定时触发任务

Qt中定时器的使用有两种方法,一种是使用QObject类提供的定时器,还有一种就是使用QTimer类。 其精确度一般依赖于操作系统和硬件,但一般支持20ms。下面将分别介绍两种方法来使用定时器。 QObject类提供的定时器 QObject中的定时器的使用&am…

Makefile 详解

文章目录1.什么是Makefile2.Makefile文件命名规则3.编写Makefile4.Makefile 的工作原理5.Makefile中的变量6.模式匹配7.函数1.什么是Makefile 一个工程中的源文件不计其数,按期类型、功能、模块分别放在若干个文件中,MakeFile文件定义了一系列的规则来制…

HIN应用调研总结

文章目录1. 代码安全iDev: enhancing social coding security by cross-platform user identification between GitHub and stack overflow【A】2. API推荐Group preference based API recommendation via heterogeneous information network【A】3.Andorid恶意软件检测Out-of-…

SSM甜品店系统计算机毕业论文java毕业设计选题源代码

💖💖更多项目资源,最下方联系我们✨✨✨✨✨✨ 目录 Java项目介绍 资料获取 Java项目介绍 计算机毕业设计java毕设之SSM甜品店系统-IT实战营_哔哩哔哩_bilibili项目资料网址: http://itzygogogo.com软件下载地址:http://itzygogogo.com/i…

中英双语多语言外贸企业网站源码系统 - HanCMS - 安装部署教程

随着跨境独立站的流行,中英双语的公司官网越来越受到重视。 此项目是基于开源CMS开发出的中英文双语外贸企业网站内容管理系统,命名HanCMS HanCMS 汉CMS中英双语多语种外贸网站系统,是一个轻量级的网站系统,访问速度极快&#xff…

[附源码]计算机毕业设计小太阳幼儿园学生管理系统Springboot程序

项目运行 环境配置: Jdk1.8 Tomcat7.0 Mysql HBuilderX(Webstorm也行) Eclispe(IntelliJ IDEA,Eclispe,MyEclispe,Sts都支持)。 项目技术: SSM mybatis Maven Vue 等等组成,B/S模式 M…

威伦触摸屏TK6060IP简单例子

详情见以下链接 https://download.csdn.net/download/weixin_39926429/87242438

[附源码]Python计算机毕业设计SSM教务管理系统(程序+LW)

项目运行 环境配置: Jdk1.8 Tomcat7.0 Mysql HBuilderX(Webstorm也行) Eclispe(IntelliJ IDEA,Eclispe,MyEclispe,Sts都支持)。 项目技术: SSM mybatis Maven Vue 等等组成,B/S模式 M…

基于连续小波变换的厄尔尼诺海平面周期变化数据集分析

基于连续小波变换的厄尔尼诺海平面周期变化数据集分析1. 厄尔尼诺海平面周期变化数据集介绍2. 基于连续小波变换的信号分析2.1 原始信号读取可视化2.2 傅里叶变换结果可视化2.3 小波变换结果可视化参考资料后记1. 厄尔尼诺海平面周期变化数据集介绍 这些数据是通过国际热带海洋…

文件上传的multipart/form-data属性,你理解了吗

form表单经常用于前端发送请求,比如:用户填写信息、选择数据、上传文件,对于不同的场景,上传数据的格式也会有些区别。 action action 表示该请求的 url 地址,定义在form上,请求的URI,可以写完…

【Python自然语言处理】文本向量化的六种常见模型讲解(独热编码、词袋模型、词频-逆文档频率模型、N元模型、单词-向量模型、文档-向量模型)

觉得有帮助请点赞关注收藏~~~ 一、文本向量化 文本向量化:将文本信息表示成能够表达文本语义的向量,是用数值向量来表示文本的语义。 词嵌入(Word Embedding):一种将文本中的词转换成数字向量的方法,属于文本向量化处理的范畴。 …

Linux操作系统~基于systemV共享内存的进程间通信

目录 一.进程间通信有哪些方式 二.什么是systemV 三.共享内存-双向通信-大致实现思路 四.4个函数about共享内存 1.shmget函数-创建 ftok函数 ​编辑 e.g. ipcs/ipcrm指令(ipc资源会被回收吗) 2.shmctl函数-删除/释放 3.shmat函数-挂接 4.shmdt…

汽车以太网简史

一、为啥需要新车载总线 在一个行业中,当一种新技术被开发和启用时,影响该技术成功的因素有很多。其中最重要的是该技术带来的益处以及自身成本。 第一个吃螃蟹的 2004年宝马决定从2008年起在其开始量产(SOP)的汽车中引入一个中…

c++ 指针

目录 1.指针的基本概念 2.定义指针,使用指针 3.指针所占的内存空间 4.空指针和野指针 4.1空指针 4.2野指针 5.const修饰指针 5.1常量指针 5.2指针常量 5.3const既修饰指针又修饰常量 6.指针和数组,利用指针访问数组 6.1概述 6.2使用数组名和下表访问 6.3使用…

【LIN总线测试】——LIN主节点数据链路层测试

系列文章目录 📒【LIN总线测试】——LIN主节点物理层测试 📒【LIN总线测试】——LIN从节点物理层测试 📒【LIN总线测试】——LIN主节点数据链路层测试 📒【LIN总线测试】——LIN主节点网络管理测试 📒【LIN总线测试】…

Docker consul的容器服务更新与发现

1)什么是服务注册与发现 服务注册与发现是微服务架构中不可或缺的重要组件。起初服务都是单节点的,不保障高可用性,也不考虑服务的压力承载,服务之间调用单纯的通过接口访问。直到后来出现了多个节点的分布式架构,起初…