Jakarta ee 为什么无状态bean被视为伪作用域,不能具有循环依赖关系?
使用Wildfly 8.1,我有几个bean,我尝试将几个EJB相互注入。假设我有3颗豆子:Jakarta ee 为什么无状态bean被视为伪作用域,不能具有循环依赖关系?,jakarta-ee,ejb,ejb-3.0,cdi,wildfly,Jakarta Ee,Ejb,Ejb 3.0,Cdi,Wildfly,使用Wildfly 8.1,我有几个bean,我尝试将几个EJB相互注入。假设我有3颗豆子: @Stateless public class A{ @Inject private B b; } @Stateless public class B{ @Inject private C c; } @Stateless public class C{ @Inject private A a; } 显然,我有循环依赖。根据规范: 容器需要支持bean中的循环 依赖关系
@Stateless
public class A{
@Inject
private B b;
}
@Stateless
public class B{
@Inject
private C c;
}
@Stateless
public class C{
@Inject
private A a;
}
显然,我有循环依赖。根据规范:
容器需要支持bean中的循环
依赖关系图,其中至少有一个bean参与每个
循环依赖链具有正常范围
在容器中运行上述代码会导致表单错误:
org.jboss.weld.exceptions.DeploymentException:weld-001443:伪作用域bean具有循环依赖关系。依赖路径:
-会话bean[类A与
限定符[@Default@Any];本地接口是
[A]
BackedAnnotatedField]@B
[……]
我的问题是:@Stateless bean的范围是什么?默认情况下是否为@Dependent?最重要的是,如何在无状态会话bean之间启用循环依赖关系
对不起,如果这个问题太琐碎了。我将感谢任何好的进一步阅读资料,将解释所提出的行为。提前谢谢
已更新
好啊我找到了解决办法。我使用了@EJB注释而不是@Inject,但这并不能解释@Inject的奇怪行为。问题仍然悬而未决,但正如Mika所建议的,CDI规范和焊接RI中可能存在未解决的问题。
@Stateless
没有范围,也与任何范围都没有关联。由于您没有在bean上注释任何其他作用域,因此您的bean最终将成为@Dependent
您需要给它们一个普通的作用域-
@RequestScoped
或@ApplicationScoped
,但是我不确定这两者在您的情况下是否有意义。这是wildfly/jboss CDI实现中的一个bug。问题描述中提供的当前解决方法(由@MikeBraun建议)是使用@EJB注释而不是@Inject。这并不能回答整个问题,但这是我搜索循环依赖项异常时在google上的第一次尝试。希望这能帮助其他程序员更快地找到答案,这就是我的解决方案
导致循环依赖项异常的代码:
class A{
@Inject B b;
public void foo(){
b.bar();
}
public void quux(){
//some code
}
}
class B{
@Inject A a;
public void bar(){
//some code
}
public void baz(){
a.quux();
}
}
解决此问题的解决方案是使用javax.enterprise.inject.Instance
class A{
@Inject B b;
public void foo(){
b.bar();
}
public void quux(){
//some code
}
}
class B{
@Inject Instance<A> a;
public void bar(){
//some code
}
public void baz(){
a.get().quux();
}
}
A类{
@注射B;
公共图书馆{
b、 bar();
}
公开无效quux(){
//一些代码
}
}
B类{
@注入实例a;
公共空白栏(){
//一些代码
}
公共图书馆{
a、 get().qux();
}
}
我没有答案,但这不是一个微不足道的问题。CDI EG成员对此进行了讨论。看看CDI规范jira,关于这个主题应该有一个问题。@MikeBraun你能提供一个jira问题的链接吗?我已经找过了,但我不确定我在找对了。它是CDI-414,谢谢。正如在描述中所写的,当前的解决方法和我在更新中所做的相同。因此,现在我将给出一个答案。CDI-414处理自注入,而不是循环注入。您的解决方案只有在web层内进行管理时才有效。因为它是EJBbean,所以在CDI实现中是一个bug。我不同意这一点。界定无状态在这里毫无意义,我认为它甚至不起作用。只有有状态bean可以有作用域。事实上,CDI对于“无状态”现象并没有一个真正令人信服的答案。无状态bean更像是侦听消息的端点,而不是普通bean。这就是为什么自注入和循环依赖不成问题的原因。无状态代理更像一个URL。当方法调用发生时,它被发送到该类型的任何bean(一个新实例,一个来自池的实例,总是相同的实例,…)。所以请求范围在这里是完全错误的。