首页 > 其他分享 >Spring Boot解决循环依赖

Spring Boot解决循环依赖

时间:2024-09-18 12:23:42浏览次数:3  
标签:依赖 Spring Boot Bean bean 实例 创建

一、前言

环依赖是指两个或者多个bean互相依赖对方,从而形成一个闭环。例如:Bean A依赖于Bean B,而Bean B又依赖于Bean A。可能会导致Spring在尝试创建这些bean实例时出现问题,因为他们互相等待对方被创建,最终导致应用程序无法启动。


Spring是如何发现这种循环依赖的问题的呢?

通过依赖图来检测和发现循环依赖问题。如下步骤:


二、Bean的创建过程

Spring容器在启动时,会扫描配置文件(appliactionContext.xml)或者注解定义的bean,并且尝试创建这些bean的实例。创建bean实例的过程如下


实例化:创建bean的实例。

属性填充:为bean注入依赖其他的bean。

初始化:执行自定义的初始化方法。

依赖注入过程

在属性填充阶段,Spring会为每个bean注入他所依赖的bean。在这个过程中,Spring会跟踪哪些bean正在被创建,以便检测循环依赖。


三、 循环依赖检测机制

Spring通过一个名为“DefaultSingletonBeanRegistry”的类来跟踪单例bean的创建状态。该类维护了三个主要的缓存来管理bean的创建过程。


singletonObjects:一级缓存(存储完全初始化好的bean)

earlySingletonObjects:二级缓存(存储早期暴露的单例bean,用于解决循环依赖)

singletonFactories:三级缓存(存储用于创建bean实例的工厂)

具体的检测步骤


3.1 实例化阶段

当Spring开始实例化一个bean时,它会将这个bean标记为正在创建。这一步是通过将bean名称添加到一个“正在创建中的bean”集合(‘singletonCurrentlyInCreaontion’)中来实现的。


3.2 属性填充阶段

在属性填充阶段,Sping会为该bean注入其依赖的其他的bean。此时Spring会检查这个“其他的bean”是否已经在创建过程中。


如果依赖的bean已经在创建中,Spring会检测到循环依赖,并根据不同的注入方式采取不同的处理方式。

如果是构造函数注入,Spring会抛出‘BeanCurrentlyInCreationException’,因为无法解决构造函数中注入的循环依赖。


如果是Setter注入,Spring会从‘earlySingletonObjects’或‘singletonFactories’中获取依赖的bean,提前暴露一个部分创建的bean引用来解决循环依赖。


举例:

如Bean A和Bean B循环依赖


@Component

public class A {

   @Autowired

   private B b;


   public A() {

       System.out.println("A is created");

   }

}


@Component

public class B {

   @Autowired

   private A a;


   public B() {

       System.out.println("B is created");

   }

}



3.3 依赖注入

Spring的依赖注入过程:


实例化Bean A

将Bean A 标记为正在创建,并添加到‘singletonCurrentlyInCreation’集合中。

实例化Bean A,并将其放入到三级缓存‘singletonFactories’中。(三级缓存存放的是创建实例化的bean工厂)


填充Bean A的属性

此时发现Bean A依赖Bean B ,于是开始创建Bean B。

将Bean B标记为正在创建,并放入到‘singletonCurrentlyInCreation’集合中。

实例化Bean B,并将其放入到三级缓存‘singletonFactories’中。


填充Bean B的属性

发现Bean B依赖于Bean A 。此时,检查到Bean A 已经在创建过程中,因此发现了循环依赖。

由于是Setter方法注入,Spring会从三级缓存‘singletonFactories’中获取一个部分创建的Bean A实例,提前暴露出来,放入二级缓存‘earlySingletonObjects’中。

使用这个部分创建出来的Bean A实例 来填充Bean B的属性。


标签:依赖,Spring,Boot,Bean,bean,实例,创建
From: https://blog.51cto.com/u_16270511/12044966

相关文章

  • 基于微信小程序UNIAPP+Spring Boot的涪陵区特色农产品交易系统
    目录前言 一、技术栈二、系统功能介绍三、核心代码1、登录模块 2、文件上传模块3、代码封装前言相比于以前的传统手工管理方式,智能化的管理方式可以大幅降低特色农产品交易的运营人员成本,实现了涪陵区特色农产品交易的标准化、制度化、程序化的管理,有效地防止了......
  • 基于Spring Boot的付费自习室管理系统
    目录前言 一、技术栈二、系统功能介绍三、核心代码1、登录模块 2、文件上传模块3、代码封装前言付费自习室管理系统采用B/S架构,数据库是MySQL。网站的搭建与开发采用了先进的java进行编写,使用了springboot框架。该系统从两个对象:由管理员和用户来对系统进行设计......
  • Springboot环球视野网站92i41--程序+源码+数据库+调试部署+开发环境
    本系统(程序+源码+数据库+调试部署+开发环境)带论文文档1万字以上,文末可获取,系统界面在最后面。系统程序文件列表开题报告内容一、项目背景与意义随着全球化进程的加速,信息交流与文化传播日益频繁,公众对于国际时事、多元文化、全球经济动态的需求日益增长。环球视野网站旨在......
  • Springboot机械零件仓储管理系统a0pe2程序+源码+数据库+调试部署+开发环境
    本系统(程序+源码+数据库+调试部署+开发环境)带论文文档1万字以上,文末可获取,系统界面在最后面。系统程序文件列表开题报告内容一、研究背景与意义随着工业化的快速发展,机械零件作为工业生产的基础组成部分,其仓储管理变得尤为重要。传统机械零件仓储管理方式存在效率低下、信......
  • Springboot基于HTML5+CSS3的信息化农村综合服务平台690g7
    本系统(程序+源码+数据库+调试部署+开发环境)带论文文档1万字以上,文末可获取,系统界面在最后面。系统程序文件列表开题报告内容一、项目背景与意义随着信息技术的飞速发展,信息化已成为推动农村经济社会发展的重要力量。构建基于HTML5+CSS3的信息化农村综合服务平台,旨在利用现......
  • Java客户端SpringDataRedis(RedisTemplate使用)
    文章目录⛄概述⛄快速入门❄️❄️导入依赖❄️❄️配置文件❄️❄️测试代码⛄数据化序列器⛄StringRedisTemplate⛄RedisTemplate的两种序列化实践方案总结⛄概述SpringData是Spring中数据操作的模块,包含对各种数据库的集成,其中对Redis的集成模块就叫做SpringDataRedis,......
  • springboot整合mybatis(使用druid线程池)
    pom引入<mybatis.version>2.3.2</mybatis.version> <druid.version>1.1.23</druid.version><!--数据库--><dependency><groupId>org.mybatis.spring.boot</groupId><art......
  • 期末前端web大作业——动漫客栈响应式bootstarp(7页) 排版整洁,内容丰富,主题鲜明 (2)
    HTML实例网页代码,本实例适合于初学HTML的同学。该实例里面有设置了css的样式设置,有div的样式格局,这个实例比较全面,有助于同学的学习,本文将介绍如何通过从头开始设计个人网站并将其转换为代码的过程来实践设计。⚽精彩专栏推荐......
  • 基于SpringBoot+vue的校园消费点评系统设计与实现
    文章目录1.前言2.详细视频演示3.论文参考4.项目运行截图5.技术框架5.1后端采用SpringBoot框架5.2前端框架Vue6.可行性分析7.系统测试7.1系统测试的目的7.2系统功能测试8.数据库表设计9.代码参考10.数据库脚本11.作者推荐项目12.为什么选择我?13.获取源......
  • 【开题报告】基于Springboot+vue基于微信小程序的手机点餐软件(程序+源码+论文) 计算机
    本系统(程序+源码)带文档lw万字以上文末可获取一份本项目的java源码和数据库参考。系统程序文件列表开题报告内容研究背景随着移动互联网技术的飞速发展和智能手机普及率的不断提高,人们的生活方式正经历着深刻的变革。餐饮行业作为传统服务业的重要组成部分,也迎来了数字化......