1. 什么是循环依赖?

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

或者两头隐含了多个 Bean,然而最终都造成了一个闭环:

循环依赖示例

@Configurationpublic 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 在启动时,会提醒有循环依赖存在,并启动失败。

2. 循环依赖的解决办法

(1)从新设计

呈现循环依赖很可能是在业务设计方面存在一些问题,所以这个时候能够先思考是否要从新正当划分类的指摘。

(2)懒加载

Spring 提供了 @Lazy 注解,来提早加载一个 bean。这种状况下,被润饰的 bean 只在第一次须要的时候才会齐全被创立。所以在循环依赖中,只须要将其中闭环中的一个 bean 提早加载,也能够解决这个问题。

@Componentstatic class A {    @Resource    private B b;    public A(@Lazy B b) {        this.b = b;    }}

(3)应用 Setter 属性注入

这是 Spring 倡议应用这种形式来解决循环依赖

@Componentstatic class A {    @Resource    private B b;    public void setB(B b) {        this.b = b;    }}