首页 > 解决方案 > spring容器如何解决循环依赖

问题描述

例如 Employee 类依赖于 Student 类,Student 类依赖于 Person 类,Person 类依赖于 Employee 类

标签: javaspringdependency-injection

解决方案


首先:尽可能避免循环依赖。
这促进了类之间的高度耦合,并使整个设计更加复杂。

这与没有 Spring 的方式相同。
使用构造函数在两个类中设置依赖关系,您会因为循环创建而陷入困境:

public Foo(Bar bar){...
}

public Bar(Foo foo){...
}

Bar bar = new Bar(new Foo(???));  // stuck
Foo foo = new Foo(new Bar(???));  // stuck

在一侧使用构造函数,在另一侧使用设置器,您可以缓解创建问题:

Foo类:

public Foo(){...
}
public setBar(Bar bar){...
}

酒吧类:

public Bar(Foo foo){...
}

你可以这样做:

Foo foo = new Foo(); // ok 
Bar bar = new Bar(foo);  // ok
foo.setBar(bar); // ok      

具体来说,在 Spring 中,如果在两个类中都使用构造函数注入,则 Spring 容器启动将失败,因为这需要使用不存在的 bean 作为 arg 实例化类(通过反射)。
如果您不同时使用构造函数注入,而是使用 setter 或字段注入,Spring 将通过分两步做事来缓解这种情况:

- instantiate the beans with the no arg constructor 
- set dependency foo in bar
- set dependency bar in foo

推荐阅读