Spring中Bean对象之间的循环依赖问题

本文探讨了Spring框架中如何处理Bean对象的循环依赖问题,主要针对@Autowired注解和构造函数引起的循环依赖。Spring通过三级缓存机制解决@Autowired注解导致的循环依赖,而在构造函数场景下,可以使用@Lazy注解或工厂方法来避免循环依赖。理解这些机制有助于优化Spring应用的性能和稳定性。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

Spring中Bean对象之间的循环依赖问题

一、对于使用Autowired注解导致的循环依赖

使用缓存解决循环依赖,Spring中的三个缓存

  • 一级缓存: 存储完整的单例Bean
  • 二级缓存:存储半成品单例Bean
  • 三级缓存:打破循环

预备知识

  • Spring中一个bean的创建过程大概为:实例化->初始化(自定义属性的依赖注入,aware属性的依赖注入,进行AOP)->使用->销毁
  • 在实例化的时候,根据构造函数创建一个bean对应的实例,在进行初始化的时候会把使用@Autowired注解的对象进行依赖注入(@Autowired注解默认required
    = true,即使用该注解的对象实例必须存在)

举例说明
下面的代码里面,AService里面依赖注入了BService,BService里面依赖注入了AService

@Service
public class AService{
	@Autowired
	private BService bService;
	
	public AService(){}
}

@Service
public class BService{
	@Autowired
	private AService aService;
	
	public BService(){}
}

在实例化的过程中,两个bean对象都可以成功的进行实例化,在进行初始化的时候,AService实例里面要依赖注入BService实例,就会执行下面的过程:
在这里插入图片描述
需要判断当前bean对象是否需要AOP,如果需要AOP的话,需要进行提前AOP,并且把半成品的代理对象放入到二级缓存里面,而不是把半成品的普通对象放入到二级缓存里面

然后对bean实例进行其他属性的赋值,这个时候的bean对象就是完整的对象,把完整的对象放入到单例池里面

Spring靠着三个缓存解决了循环依赖

二、对于构造函数导致的循环依赖

1. 使用@Lazy注解
使用Lazy注解打破循环,Spring会直接生成BService的代理对象(和AOP的代理对象没有关系,是Spring直接基于cglib生成的代理对象,不涉及去创建BService的bean,直接创建BService的代理),然后就把BService的代理对象传给A。
2. 使用工厂方法来创建bean对象
使用工厂方法创建对象,只有在对象使用的时候才会进行创建,这样就不会出现循环依赖

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值