我读过circular dependencies
是由setter
注射引起的。所以我试着自己检查一下。而且我似乎只能通过circular dependency
注入重现constructor
(请参阅下面的代码)。
所以问题:
circular dependency
注射来完成setter
吗?如何解决以下代码中的circular dependencies
?
public class AConstr {
private final BConstr b;
public AConstr(BConstr bConstr) {
System.out.println("AConstructor:: constructor");
this.b = bConstr;
}
}
public class BConstr {
private final AConstr a;
public BConstr(AConstr aConstr) {
System.out.println("BConstructor:: constructor");
this.a = aConstr;
}
}
<bean id="aConstr" class="pack.bean.AConstr">
<constructor-arg ref="bConstr"/>
</bean>
<bean id="bConstr" class="pack.bean.BConstr">
<constructor-arg ref="aConstr"/>
</bean>
答案 0 :(得分:1)
请参阅循环依赖性仅由构造函数注入引起。在您的示例中,您可以使用setter而不是构造函数。
如果是构造函数注入,它将在构造函数中说AConstr
,并且在执行BConstr
之前它将再次注意AConstr
转到BConstr
并尝试创建BConstr
的对象。
现在它将控制将来到BConstr
的构造函数,然后它会找到依赖项'AConstr'。这将创造永无止境的连锁店。
在Setter注入期间为了注入一个对象,它将创建该对象。如果你有二次注射,那就没问题了。
所以当你打电话
context.getBean("aConstr");
首先创建一个aConstr
对象,然后调用setter注入,进一步将依赖注入为bConstr
。
答案 1 :(得分:1)
我知道答案有点迟,但迟到总比没有好:
如果您仔细阅读该文章,您会发现可能您的设计错误: http://misko.hevery.com/2008/08/01/circular-dependency-in-constructors-and-dependency-injection/
Setter注入只会隐藏它。
答案 2 :(得分:1)
有两种方法可以使用Spring FooController BarController
+ +
| |
+ +
FooService<-------->BarService
+ +
| |
+ +
FooJpaRepository BarJpaRepository
+ +
| |
+ +
FooEntity BarEntity
注入依赖项: field 或构造函数。
如果您有以下图层:
使用以下绑定:
@Autowired
因此,2 Services 可以相互依赖(直接或不相关)是正常的,这就是为什么你可以打破循环依赖:
@Lazy
,而不是在您的某个服务中使用构造函数 public ArrayList<Song> arrayOfSongs;
public SongsAdapter adapter;
。这是Spring建议的内容:https://docs.spring.io/spring/docs/current/spring-framework-reference/core.html#beans-dependencies
另一方面,应该通过构造函数服务(或直接 JpaRepository )注入 RestControllers >。在这种情况下,循环依赖将是架构问题。