为什么无状态bean被视为伪范围并且不能具有循环依赖性?

时间:2014-10-20 14:05:12

标签: java-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中的圆形   依赖图,其中至少有一个bean参与其中   循环依赖链具有正常范围

在容器中运行上面的代码会导致格式错误:

  

org.jboss.weld.exceptions.DeploymentException:WELD-001443:伪范围bean具有循环依赖关系。依赖路径:

     

-Session bean [A类用   限定词[@Default @Any];本地接口是   [一个]   BackedAnnotatedField] @Inject private B,

     

[..]

我的问题是:@Stateless bean的范围是什么?它默认是@Dependent吗?最重要的是如何在无状态会话bean之间启用循环依赖?

很抱歉,如果这个问题太微不足道了。我将非常感谢任何可以解释所呈现行为的进一步阅读资源。提前谢谢。

已更新 好。我找到了解决方法。我使用@EJB注释而不是@Inject,但这并不能解释@Inject的奇怪行为。这个问题仍未解决,但正如Mika所说,CDI规范和Weld RI可能都是未解决的问题。

3 个答案:

答案 0 :(得分:9)

这是wildfly / jboss CDI实施中的一个错误。问题描述https://issues.jboss.org/browse/CDI-414中提供的当前解决方法(由@MikeBraun建议)是使用@EJB注释而不是@Inject。

答案 1 :(得分:3)

@Stateless没有范围,与任何范围都没有关联。由于您没有在bean上注释任何其他范围,因此您的bean最终为@Dependent

你需要给他们一个正常范围 - @RequestScoped@ApplicationScoped,但我不确定你的情况是否有意义。

答案 2 :(得分:1)

这并没有回答整个问题,但是当我搜索循环依赖项异常时,这是谷歌的第一次打击。希望这将有助于其他程序员在这里找到更快的答案是我的解决方案。

导致循环依赖性异常的代码:

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();
    }
}
相关问题