哪些循环依赖问题Spring解决不了?
前言
大家都知道 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,并抛出了异常。

解决:
在需要循环注入的属性上添加 @Lazy
场景二: constructor 注入的循环依赖
描述: A --> B --> A,且 都是通过构造函数依赖的
@Service
public class A {
private B b;
public A(B b) {
this.b=b;

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

5008

被折叠的 条评论
为什么被折叠?



