Jakarta ee 为什么无状态bean被视为伪作用域,不能具有循环依赖关系?

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中的循环 依赖关系

使用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中的循环 依赖关系图,其中至少有一个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(一个新实例,一个来自池的实例,总是相同的实例,…)。所以请求范围在这里是完全错误的。