首页 > 其他分享 >Spring 如何解决循环依赖?

Spring 如何解决循环依赖?

时间:2024-12-15 20:53:03浏览次数:5  
标签:初始化 缓存 Spring Bean 依赖 循环

Spring通过三级缓存机制来解决单例Bean的Setter或字段注入类型的循环依赖问题。以下是Spring解决循环依赖的核心流程:

1. 三级缓存介绍
Spring容器为了解决循环依赖,维护了以下三个缓存:

  • 一级缓存(singletonObjects):已完全初始化的单例Bean。
  • 二级缓存(earlySingletonObjects):早期暴露的Bean(未完全初始化,但已注入必要属性)。
  • 三级缓存(singletonFactories):存储创建Bean的工厂,允许获取Bean的代理对象。

2. 解决循环依赖的关键流程
以下是Spring处理循环依赖的步骤:

  1. 创建Bean实例
    Spring在实例化一个Bean时,首先会在一级缓存中查找。如果未找到,会尝试通过三级缓存提前暴露一个工厂,用于生成当前正在创建的Bean的早期引用。

  2. 将早期引用暴露到三级缓存
    Spring在Bean实例化之后,尚未填充属性之前,会将Bean的ObjectFactory(一个创建Bean早期引用的工厂)存入三级缓存。

  3. 填充依赖
    在填充Bean的依赖时,如果发现需要依赖另一个Bean且该Bean正在创建中,Spring会从三级缓存中获取早期引用,并注入到当前Bean中。

  4. 完成初始化
    当Bean完成属性注入并经过初始化回调后,Spring会将完全初始化的Bean移入一级缓存,同时从二级和三级缓存中移除该Bean的引用。

3. 示例代码
以循环依赖为例:

@Component
public class BeanA {
    @Autowired
    private BeanB beanB;
}

@Component
public class BeanB {
    @Autowired
    private BeanA beanA;
}

Spring解决的流程:

  1. 初始化BeanA,发现依赖BeanB;
  2. 开始初始化BeanB,发现依赖BeanA;
  3. 从三级缓存中获取BeanA的早期引用,将其注入到BeanB;
  4. BeanB完成初始化,存入一级缓存;
  5. 返回继续完成BeanA的初始化。

4. 注意事项

  1. 仅适用于单例作用域
    Spring的三级缓存机制仅适用于单例Bean。Prototype作用域的Bean不受容器管理,无法提前暴露早期引用,因此无法解决循环依赖。

  2. 构造器注入无法解决
    构造器注入要求在实例化时提供完整依赖,而此时无法提前暴露引用,Spring会直接抛出BeanCurrentlyInCreationException。

5. 如何避免循环依赖
虽然Spring能够解决部分循环依赖,但实际开发中,建议通过以下方式避免:

  • 优化设计,拆分循环依赖。
  • 使用@Lazy懒加载,延迟依赖的注入时机。
  • 引入接口或事件机制,解耦Bean之间的直接依赖。

总结:
Spring通过三级缓存机制解决了Setter和字段注入的循环依赖问题,而构造器注入和Prototype作用域需要开发者自行设计规避。

标签:初始化,缓存,Spring,Bean,依赖,循环
From: https://www.cnblogs.com/eiffelzero/p/18608700

相关文章

  • 基于SpringBoot+vue的商城停车场管理系统(2024-2025年最新,原创项目)
    文章目录系统演示录像系统实际运行效果图技术框架SpringBoot-后端开发框架Vue-前端开发框架前后端分离的开发流程可行性分析系统测试系统测试的目的系统功能测试数据库表设计(供参考)1.用户表(t_user)2.角色表(t_role)3.权限表(t_permission)4.用户-角色关联表(t_user_r......
  • 基于SpringBoot + Vue的超市外卖系统的设计与实现(精选计算机毕业设计-源码+文档+部署)
    文章目录系统演示录像系统实际运行效果图技术框架SpringBoot-后端开发框架Vue-前端开发框架前后端分离的开发流程可行性分析系统测试系统测试的目的系统功能测试数据库表设计(供参考)1.用户表(t_user)2.角色表(t_role)3.权限表(t_permission)4.用户-角色关联表(t_user_r......
  • java&springboot&msyql进出校园门禁管理系统79219-计算机毕业设计 原创(附源码)
    摘 要信息化的进出校园门禁管理可以节省人力和物力,并且具有较高的精确性。随着计算机技术和网络技术的迅猛发展,进出校园门禁管理系统不断向着集成化、智能化、网络化与分布式的方向发展。本文主要针对目前大部分高校校园进出管理方式落后、管理效率低下的状况,结合当前最新......
  • 基于java+Springboot+MySQL微信小程序的大用户心理咨询系统设计与实现99040-计算机原
    目录1绪论1.1研究背景1.2研究现状1.3论文结构与章节安排2 基于微信小程序的大用户心理咨询系统设计与实现分析2.1可行性分析2.2系统功能分析2.3 系统用例分析2.4系统流程分析2.5本章小结3基于微信小程序的大用户心理咨询系统设计与实现总体设计......
  • 探索Spring之利剑:ApplicationContext接口
    嘿,开发者们!你是否曾在构建Spring应用时,感到困惑于那些复杂的配置和神秘的容器?今天,我们将揭开Spring中一个核心接口——ApplicationContext​的神秘面纱。这不仅是一篇技术文章,更是一次深入Spring心脏的探险之旅。系好安全带,我们即将启程!......
  • 【队列习题】如果允许在循环队列的两端都可以进行插入和删除操作,要求:写出循环队列的类
    题目如果允许在循环队列的两端都可以进行插入和删除操作,要求:写出循环队列的类型定义。分别写出从队尾删除和从队头插入的算法。分析本题实际上是求双端队列的操作约束队头指针指向队头元素的上一个位置队尾指针指向队尾元素1.双端队列的存储结构跟队列的存储结构相......
  • springboot启动流程
    普通springboot的启动类importorg.springframework.boot.SpringApplication;importorg.springframework.boot.autoconfigure.SpringBootApplication;@SpringBootApplicationpublicclassDemoApplication{publicstaticvoidmain(String[]args){Spri......
  • Springboot计算机毕业设计校刊投稿系统ru0o2
    Springboot计算机毕业设计校刊投稿系统ru0o2本系统(程序+源码+数据库+调试部署+开发环境)带论文文档1万字以上,文末可获取,系统界面在最后面。系统程序文件列表项目功能:用户,编辑人员,稿件类型,在线投稿,专家,专家审核,文章分类,文章信息,稿件归档开题报告内容Springboot......
  • spring cloud open feign header 参数传递
    consumer配置以下内容```javapackagecom.me.consumer.config;importfeign.RequestInterceptor;importfeign.RequestTemplate;importorg.springframework.context.annotation.Bean;importorg.springframework.context.annotation.Configuration;importorg.spri......
  • 基于Springboot校园运动会报名管理系统网站设计与实现(作品+论文+开题报告)
     博主介绍:黄菊华老师《Vue.js入门与商城开发实战》《微信小程序商城开发》图书作者,CSDN博客专家,在线教育专家,CSDN钻石讲师;专注大学生毕业设计教育、辅导。所有项目都配有从入门到精通的基础知识视频课程,学习后应对毕业设计答辩,提供核心代码讲解,答辩指导。项目配有对应开发......