依赖注入EJB 3 - 选择太多了?

时间:2011-03-14 09:36:10

标签: java spring dependency-injection ejb cdi

我们正在开始一个基于EJB 3.0的新项目。我有一个“基于弹簧”的背景(并且喜欢它),所以对我来说松耦合和可测试性是一个很大的必须。这篇文章不应该是关于“ejb vs. spring”。如果您已经拥有真正的项目经验,那将是完美的。

这里有一些示例代码来演示这个问题:

客户 - > ejb - >合作者1 - >合作者.. - >合作者

<!-- language: java -->
@Stateless
public class SampleService {

    // or @Inject via CDI
    // or @Autowired via Spring
    @EJB // or just use a stateless session bean via EJB 3.0
    private Bank bank;

    // same for this component
    @EJB
    private Calculator calc;

    // both collaborators must be settable from outside, to make everything testable (and mockable)

    /**
     * sample "business service" called from client
     */
    public void debit(BigDecimal amount){
        calc.calculate(amount.subtract(new BigDecimal(100)));
        bank.debit(amount);
    }

}

// or via @Component (Spring), or CDI?
@Stateless // or Stateless Session bean with optional @Service/@Singleton annotation?
public class Calculator {
    public void calculate(BigDecimal subtract) {
        // calculate stuff....
    }
}

// or via @Component (Spring), or CDI?
@Stateless // or Stateless Session bean with optional @Service/@Singleton annotation?
public class Bank {
    public void debit(BigDecimal amount) {
        // ...
    }
}

我想知道在ejb 3.0中为所有协作者及其协作者实现依赖注入的最佳方法是什么?这种意义上的合作者可以是非常小的专门课程。

到目前为止,我们已经讨论了以下选项,并且总是没有得到正确的结论:)

  1. 只使用ejb标准,其中包含无状态会话bean以及所有后果(如汇集,资源处理等)。

  2. 使用无状态会话bean作为“业务组件”(入口点)并从那里开始

  3. a)弹簧有线依赖(通过“jboss snowdrop”集成)

    b)CDI有线依赖(通过WELD for ejb 3.0和jboss eap 5.1)

    我不需要知道如何在单元测试中使用bean。我所追求的答案是在运行的应用程序服务器中连接所有依赖项的最佳方法是什么(spring vs. guice vs. CDI vs. EJB)。我只需要从外部EJB(“业务入口点”)向下知道图形。所以外面的一切(servlets,前端等)这个问题的范围:)

    请假设为项目设置了EJB 3.0和jboss eap 5.1:)

    期待您的答案,并希望有一些基于项目的知识。

4 个答案:

答案 0 :(得分:4)

如果您需要方法级事务管理,安全性,并发管理或会话bean可以提供的任何其他服务,那么将它们作为EJB会话bean。您可以从托管bean开始,然后在需要时创建会话bean。

如果要将这些会话bean注入托管bean(在CDI中是jar文件中包含meta-inf目录中的beans.xml文件的任何内容),请使用@EJB。如果要将普通托管bean注入会话bean,请使用@Inject。

如果要注入远程会话bean(或任何Java EE远程资源),则此链接将说明如何通过适配器类执行此操作。本质上,它将所有讨厌的字符串保存在一个地方,然后允许您像处理任何其他可注入bean一样处理这些远程资源(通过适配器成员变量上的@Produces注释)。您不必这样做但建议使用它。

Typesafe resource injection

答案 1 :(得分:2)

总的来说,在Java中有“选择太多”,所以在这方面肯定也是如此。我不会将EJB描述为通用的依赖注入框架,而是将DI用于其目的。如果这是您想要编码的方式,那么您应该为此添加一个框架。如果你知道并喜欢Spring,那就去吧。我已经使用Guice和EJB(here是一本很好的食谱),如果你需要另一个框架来弄清楚如何做到这一点,那么效果也很好。

答案 2 :(得分:2)

我肯定会反对混合框架。

我正在研究一个挂在EJB,Spring和JBoss Seam上的项目(还有一半Flex,半JSF前端)。真正的科技动物园!
无论如何,将它们连接在一起并不是最糟糕的部分,这些框架具有灵活的注入功能。测试也或多或少都可以忍受 最痛苦的是摆脱不同生命周期模型导致的内存泄漏,同步事务和清理线程行为。

现在我们转向纯Java EE 6(摆脱Spring,Flex并从Seam转移到CDI)。到目前为止,我们对结果非常满意。 顺便说一下,我不批评春天。坚持使用Java EE或Spring堆栈,混合它们只是在寻找麻烦。

答案 3 :(得分:0)

如果您的主要目标是允许依赖注入进行测试,我建议您只需将这些值设置为受保护或给予设置者即可设置这些值。我喜欢使用Mockito来存储Java EE EJB 3.0中的所有内容,以及在集成测试之外进行任何测试时只允许Mockito为我存储方法,但是如果你正在寻找完全依赖注入,比如能够拥有几个不同的bean基于同一个类,但我会推荐不同的依赖,因为Yishai说和Spring一起去。