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

spring循环依赖解决

问题描述

spring循环依赖是对于ioc容器。类A、B、C,类A依赖了B,类A依赖了C,类B依赖了A,类C依赖了A。假如现在类A需要放到ioc,属性赋值的时候会去找B这个bean,但是B不存在,于是去创建B这个bean,但是实例化beanB之后再属性赋值的时候需要注入A这个bean。这样就造成了循环。

解决办法

spring通过三级缓存解决循环依赖问题,首次注入beanA的时候会在类A实例化之后,spring会创建一个ObjectFactory用来后续获取beanA的早期引用,并将这个ObjectFactory放到三级缓存中。接着注入beanB,初始化类B之后属性赋值,需要注入beanA,这是spring会去三级缓存中获取A的ObjectFactory调用getObject()获取A的早期引用,如果A需要被代理(如@Transactional),会在此时去创建A的代理对象,放到二级缓存中,然后删除三级缓存的A的工厂对象。此时returnA这时循环有了出口,就解决了循环依赖。

补充

时序图

  • 实例化->new A(这里把创建A的ObjectFactory放到三级缓存)
  • 属性赋值(循环依赖的时候这里去创建AOP代理)
  • 初始化(正常这里创建aop代理)

三级缓存是为了支持aop代理的按需创建。二级缓存的话就是直接把早期对象放到二级缓存,实例化A之后马上把他放到二级缓存。如果直接把早期对象放到二级缓存,(实例化之后)就无法灵活决定是否创建代理(因为AOP代理是在postProcessAfterInitialization(上图初始化中)中创建的)。可能导致重复创建代理或代理失效。
而如果是三级缓存的话

spring创建一个bean的阶段

1.实例化(instantiation)      ->new A()
2.属性注入(Populate Properties->setB(),setC()
3.初始化(Initialization->调用init-method,BeanPostProcessorpostProcessBeforeInitialization//是BeanPostProcessor的方法初始化方法(@PostConstruct,init-method)postProcessAfterInitialization ->AOP代理就在这里创建!//是BeanPostProcessor的方法
4.放入一级缓存(singletonObject)

Spring 提供了 InstantiationAwareBeanPostProcessor.getEarlyBeanReference() 方法,允许 AOP 模块在早期引用阶段就决定是否创建代理。这个方法会在 ObjectFactory.getObject() 被调用时触发,是提前创建代理的关键入口

代码细节

三级缓存:singletonFactories如下

Map<String, ObjectFactory<?>> singletonFactories

其中键是类名首字母小写。

http://www.dtcms.com/a/315481.html

相关文章:

  • 一(3)理解 newNode->next = head 和 Node* temp = head 的区别
  • UF_MODL_ask_curve_points 离散曲线,按长度分段曲线,不准确 不知道为啥
  • 面向对象的七大设计原则
  • 【音视频】WebRTC 一对一通话-信令服
  • 【计算机网络】6应用层
  • 【Qt开发】常用控件(一)
  • IP证书使用场景及注意事项
  • 16-Chapter03-Example01
  • Android Studio下载及安装配置
  • MyBatis实现SQL
  • 如何通过视觉+自动化组合拳提升UI测试的质量
  • 扣子Coze中的触发器实现流程自动化-实现每日新闻卡片式推送
  • 深入浅出 RabbitMQ-路由模式详解
  • 【2025年8月5日】mysql-8.0.38-linux-glibc2.12-x86_64.tar.xz 安装MySQL操作指引
  • 数据结构(01)—— 数据结构的基本概念
  • Wisdom SSH:自动化网络配置管理的领航者
  • 工业级 CAN 与以太网桥梁:串口服务器CAN通讯转换器深度解析(下)
  • 基于deepSeek的流式数据自动化规则清洗案例【数据治理领域AI带来的改变】
  • wps创建编辑excel customHeight 属性不是标准 Excel Open XML导致比对异常
  • 用 Python 批量处理 Excel:从重复值清洗到数据可视化
  • Unity编辑器工具:一键为场景中所有MeshRenderer对象添加指定脚本
  • 如何在服务器上部署后端程序和前端页面?
  • 在Spring Boot项目中动态切换数据源和数据库!
  • # 【Java + EasyExcel 实战】动态列 + 公式备注 Excel 模板导出全流程(附完整代码)
  • 前端实现Excel文件的在线预览效果
  • 【学习笔记】FTP库函数学习
  • 文件编译、调试及库制作
  • 人工智能领域、图欧科技、IMYAI智能助手2025年2月更新月报
  • pyspark中的kafka的读和写案例操作
  • Goby 漏洞安全通告| NestJS DevTools /inspector/graph/interact 命令执行漏洞(CVE-2025-54782)