【Spring源码三千问】哪些循环依赖问题Spring解决不了?

Spring在某些特定场景下无法解决循环依赖,包括prototype作用域的循环依赖、构造器注入的循环依赖以及@Async注解的AOP代理Bean的循环依赖。当遇到这些问题时,可以使用@Lazy注解来解决。@Lazy可以在构造器或属性注入中使用,以延迟初始化,避免循环依赖导致的错误。

前言

大家都知道 Spring 解决了循环依赖的问题,网上也可以搜到 Spring 是使用三级缓存来解决循环依赖的。
但有些时候循环依赖问题还是会导致启动报错。
也就说明,在某些情况下,Spring 是没有办法解决循环依赖问题的。
我们就来探究一下,哪些循环依赖场景是 Spring 没办法解决的?

版本约定

Spring 5.3.9 (通过 SpringBoot 2.5.3 间接引入的依赖)

正文

场景一: prototype 类型的循环依赖

描述: A --> B --> A,且 A,B 都是 scope=prototype

@Service
@Scope("prototype")
public class A {
   
   
    @Autowired
    private B b;
}

@Service
@Scope("prototype")
public class B {
   
   
    @Autowired
    private A a;
}

这种场景下会报如下错误:

Exception in thread "main" org.springframework.beans.factory.UnsatisfiedDependencyException: 
Error creating bean with name 'c1Service': Unsatisfied dependency expressed through field 'c2Service'; 
nested exception is org.springframework.beans.factory.UnsatisfiedDependencyException: Error creating bean with name 'c2Service': Unsatisfied dependency expressed through field 'c1Service'; 
nested exception is org.springframework.beans.factory.BeanCurrentlyInCreationException: Error creating bean with name 'c1Service': Requested bean is currently in creation: Is there an unresolvable circular reference?

分析:
A 实例创建后,populateBean 时,会触发 B 的加载。
B 实例创建后,populateBean 时,会触发 A 的加载。由于 A 的 scope=prototype,从缓存中获取不到 A,要创建一个全新的 A。
这样,就会进入一个死循环。Spring 肯定是解决不了这种情况下的循环依赖的。所以,提前进行了 check,并抛出了异常。

prototypeCircleRefer

解决:
在需要循环注入的属性上添加 @Lazy

场景二: constructor 注入的循环依赖

描述: A --> B --> A,且 都是通过构造函数依赖的


@Service
public class A {
   
   
    private B b;
    
    public A(B b) {
   
   
        this.b=b;
    
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

老王学源码

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值