Spring Bean循环依赖详解

简介: 【6月更文挑战第2天】

Spring Bean循环依赖详解

1. 引言

在Spring框架中,Bean循环依赖是一个常见问题。循环依赖发生在两个或多个Bean相互持有对方的引用时,这可能导致Spring容器无法正常启动。尽管Spring支持一定程度的循环依赖,但在某些情况下,应用仍可能遇到启动错误。本文将深入探讨Spring如何解决Bean循环依赖的问题。

2. Bean循环依赖的概念

2.1 什么是Bean循环依赖?

循环依赖是指在Spring容器中,两个或多个Bean对象之间形成引用循环。这分为两种情况:

  • 相互依赖:Bean A依赖于Bean B,同时Bean B也依赖于Bean A。
  • 自我依赖:一个Bean依赖于它自己。

2.2 Spring创建Bean的主要流程

Spring容器创建Bean的流程大致分为三个步骤:

  1. 实例化Bean:通过反射调用无参构造函数创建Bean实例。
  2. 填充Bean属性:对Bean中的属性进行依赖注入。
  3. 调用Bean初始化方法:完成Bean的初始化操作,如调用init-method或通过BeanPostProcessor进行AOP代理。

3. Spring如何解决循环依赖

3.1 三级缓存的作用

Spring使用三级缓存机制来解决循环依赖问题:

  • 一级缓存(singletonObjects):存放已完成初始化的单例Bean实例。
  • 二级缓存(earlySingletonObjects):存放已完成实例化但属性未注入的Bean。
  • 三级缓存(singletonFactories):存放Bean工厂对象,用于生成Bean的早期引用。

3.2 三级缓存解决循环依赖的过程

当Spring创建一个Bean时,它会按照以下顺序检查缓存:

  1. 检查一级缓存中是否已有该Bean的实例。
  2. 如果没有,检查三级缓存以获取Bean的工厂对象。
  3. 如果工厂对象存在,调用它来创建Bean的早期引用,并将其放入二级缓存。
  4. 继续创建Bean的过程,包括属性填充和初始化。
  5. 最后,将完全初始化的Bean放入一级缓存。

3.3 AOP与循环依赖

当涉及到AOP时,Spring的处理方式略有不同。在创建代理Bean时,Spring会在getEarlyBeanReference方法中提前创建代理对象,并将代理对象放入二级缓存。这样,即使存在循环依赖,其他Bean也能通过代理对象完成属性注入。

4. 应用报错分析

尽管Spring有机制解决循环依赖,但在实际应用中,我们仍可能遇到问题。错误通常发生在Bean的最终版本与注入的版本不一致时。这可能是因为:

  • 存在多个AOP切面,它们在不同的时机对同一个Bean进行代理。
  • Spring容器加载Bean的顺序不确定,导致在不同环境下可能出现不同的问题。

请注意,本技术文章基于阿里云开发者社区提供的内容,并进行了适当的扩展和解释。在实际开发中,建议深入理解Spring框架的工作原理,并遵循最佳实践来避免循环依赖问题。

目录
相关文章
|
14天前
|
XML Java 数据格式
Spring5系列学习文章分享---第一篇(概述+特点+IOC原理+IOC并操作之bean的XML管理操作)
Spring5系列学习文章分享---第一篇(概述+特点+IOC原理+IOC并操作之bean的XML管理操作)
18 1
|
14天前
|
XML druid Java
Spring5系列学习文章分享---第二篇(IOC的bean管理factory+Bean作用域与生命周期+自动装配+基于注解管理+外部属性管理之druid)
Spring5系列学习文章分享---第二篇(IOC的bean管理factory+Bean作用域与生命周期+自动装配+基于注解管理+外部属性管理之druid)
21 0
|
11天前
|
JavaScript Java Maven
理解固化的Maven依赖:spring-boot-starter-parent 与 spring-boot-dependencies
理解固化的Maven依赖:spring-boot-starter-parent 与 spring-boot-dependencies
44 1
|
16天前
|
Java Spring 容器
解读spring5源码中实例化单例bean的调用链
解读spring5源码中实例化单例bean的调用链
|
18天前
|
运维 Java 关系型数据库
Spring运维之boot项目bean属性的绑定读取与校验
Spring运维之boot项目bean属性的绑定读取与校验
23 2
|
23天前
|
Java 开发者 Spring
Spring 中 Bean 的生命周期
Spring 中 Bean 的生命周期
15 2
|
7天前
|
Java 微服务 Spring
微服务04---服务远程调用,根据订单id查询订单功能,根据id查询订单的同时,把订单所属的用户信息一起返回,Spring提供了一个工具RestTemplate,Bean写在对象前面,以后可以在任何地
微服务04---服务远程调用,根据订单id查询订单功能,根据id查询订单的同时,把订单所属的用户信息一起返回,Spring提供了一个工具RestTemplate,Bean写在对象前面,以后可以在任何地
|
14天前
|
Java Spring
Spring注解内容----用来替代Bean
Spring注解内容----用来替代Bean
|
15天前
|
Java Linux 程序员
技术笔记:Spring生态研习【五】:Springboot中bean的条件注入
技术笔记:Spring生态研习【五】:Springboot中bean的条件注入
|
16天前
|
Java Spring
聊聊Spring中两种创建Bean的方式:BeanDefinition.setInstanceSupplier() 和 FactoryBean
聊聊Spring中两种创建Bean的方式:BeanDefinition.setInstanceSupplier() 和 FactoryBean