【问题标题】:CDI injection loopCDI 注入回路
【发布时间】:2013-03-08 17:59:46
【问题描述】:

我在 JBoss 7.1.1 中遇到了将 CDI 注入 Weld 容器的问题

我有以下对象模型:

@Stateless
class ServiceEjb {
@Inject
A a;
}

class A {
@Inject
B b;
}

class B {
@Inject
A a;
}

当尝试在我的无状态类中注入 A 或 B 时,注入循环并因 javax.enterprise.inject.CreationException 而崩溃。

我尝试了很多事情(范围界定,A 或 B 上的 @Singleton 但没有成功)。 我不想破坏代码,这些注入是有道理的。

任何线索将不胜感激。

【问题讨论】:

    标签: dependency-injection cdi circular-dependency jboss-weld


    【解决方案1】:

    Circular dependency injection is not required by the CDI standard,除非循环中至少有一个 bean 具有normal scope最简单的解决方案是给 A 或 B 一个正常的范围。如果你不能给任何一个正常的范围(从代码模型来看,它们似乎都有默认的 @987654326 @ 伪范围),您将不得不寻找其他解决方案。发布一个真实的代码示例可能会让我们为您提供特定的解决方案,但这里是一个开始:

    • A 和 B 可以合并到同一个类中吗?
    • 能否从 A 和 B 中提取一个新类 C,以便 A 和 B @Inject C 相互替代?

    以下是一些 SO 链接,其中包含您可能会觉得有帮助的其他解决方案:

    MVP with CDI; avoiding circular dependency

    https://stackoverflow.com/questions/14044538/how-to-avoid-cdi-circular-dependency

    【讨论】:

    • 感谢您的快速回复。我不得不承认,正常范围的概念对我来说不是很清楚。您提供的链接是关于 @NormalScope 的,但这不存在。如何声明一个正常的范围?
    • Most scopes are normal scopes. 会话、应用程序、会话和请求范围是正常范围。这与 pseudoscopes 形成对比:单例和依赖(当您不写入范围注释时,这是默认设置)。
    • 所以,因为我已经尝试声明范围,如果我理解得很好,这应该可以工作。我可以对 DAO(由 SessionBean 访问)尝试什么样的范围?
    • 感谢您的帮助!我已经使用 @ApplicationScoped 了!不知道拥有 DAO ApplicationScoped 是否是个好主意。在 EJB jar 的情况下,这是否等同于 Singleton。
    【解决方案2】:

    我通过明确使用javax.inject.Provider 解决了这个问题。虽然我觉得这应该由 WELD 在后台自动完成,但对我来说也不是这样。这对我有用并解决了我的相关问题。

    class A {
        @Inject
        Provider<B> b; // access with b.get()
    }
    
    class B {
        @Inject
        Provider<A> a; // access with a.get()
    }
    

    我还没有测试过,但是使用一个 Provider 来打破循环就足够了,即您不需要在两个类中都使用它。

    【讨论】:

      【解决方案3】:

      您应该注入一个 Instance 而不是 B(和/或 Instance 而不是 A)

      【讨论】:

        猜你喜欢
        • 2016-09-17
        • 1970-01-01
        • 1970-01-01
        • 2023-04-07
        • 2017-10-25
        • 2014-06-02
        • 1970-01-01
        • 1970-01-01
        相关资源
        最近更新 更多