1. 什么是循环依赖?

当一个 Bean A 依赖另外一个 Bean BBean B 又依赖 Bean A 时,即发生了循环依赖。如图所示:

image.png

或者中间隐含了多个 Bean,但是最终都形成了一个闭环:

image.png

循环依赖示例

@Configuration
public class BeanCircularDependencies {

    @Component
    static class A {

        @Resource
        private B b;

        public A(B b) {
            this.b = b;
        }
    }

    @Component
    static class B {

        @Resource
        private C c;

        public B(C c) {
            this.c = c;
        }
    }

    @Component
    static class C {

        @Resource
        private A a;

        public C(A a) {
            this.a = a;
        }
    }
}

Spring 在启动时,会提示有循环依赖存在,并启动失败。

image.png

2. 循环依赖的解决方法

(1)重新设计

出现循环依赖很可能是在业务设计方面存在一些问题,所以这个时候可以先考虑是否要重新合理划分类的指责。

(2)懒加载

Spring 提供了 @Lazy 注解,来延迟加载一个 bean。这种情况下,被修饰的 bean 只在第一次需要的时候才会完全被创建。所以在循环依赖中,只需要将其中闭环中的一个 bean 延迟加载,也可以解决这个问题。

@Component
static class A {

    @Resource
    private B b;

    public A(@Lazy B b) {
        this.b = b;
    }
}

(3)使用 Setter 属性注入

这是 Spring 建议使用这种方式来解决循环依赖

@Component
static class A {

    @Resource
    private B b;

    public void setB(B b) {
        this.b = b;
    }
}

其它的解决方式,例如:使用@PostConstruct 或者 ApplicationContextAware,可以参考 Circular Dependencies in Spring


寒拾
5 声望0 粉丝

我思故我在