【问题标题】:Should I use @EJB or @Inject我应该使用@EJB 还是@Inject
【发布时间】:2011-12-29 14:36:31
【问题描述】:

我发现了这个问题:What is the difference between @Inject and @EJB,但我没有得到更明智的答案。我之前没有做过 Java EE,也没有依赖注入的经验,所以我不明白我应该使用什么?

@EJB 是旧的注入方式吗?在使用@Inject 使用新的CDI 框架时使用此注解时是否由EJB 容器完成注入?这就是区别吗?如果是这种情况,我应该使用@Inject 而不是@EJB

【问题讨论】:

    标签: java jakarta-ee ejb cdi


    【解决方案1】:

    @Inject 可以注入任何 bean,而@EJB 只能注入 EJB。您可以使用其中任何一个来注入 EJB,但我更喜欢 @Inject 无处不在。

    【讨论】:

    • 当我们使用@Inject 时,究竟是什么导致了注入? JavaEE 容器?可以注入 POJO 的吗?
    • 对于 CDI,它是 CDI 容器(捆绑在 JavaEE 容器中)
    【解决方案2】:

    @EJB 仅用于注入 EJB,并且已经存在相当长的一段时间了。 @Inject 可以注入任何托管 bean,并且是新 CDI 规范的一部分(从 Java EE 6 开始)。

    在简单的情况下,您只需将@EJB 更改为@Inject。在更高级的情况下(例如,当您严重依赖@EJB 的属性,如beanNamelookupbeanInterface)而不是为了使用@Inject,您需要定义@Producer 字段或方法.

    这些资源可能有助于了解 @EJB@Produces 之间的区别以及如何充分利用它们:

    安东尼奥·贡萨尔维斯的博客:
    CDI Part I
    CDI Part II
    CDI Part III

    JBoss Weld 文档:
    CDI and the Java EE ecosystem

    堆栈溢出:
    Inject @EJB bean based on conditions

    【讨论】:

    • 为什么@EJB 用于循环注入(一个单例bean 和另一个bean 需要相互引用)? (参考下面我的回答 - 我不确定我是否通过切换到@EJB 做正确的事情)
    • 因为您不是在注入实现,而是插入实现的代理。因此,您可以获得“后期绑定”和其他容器功能的优势。
    【解决方案3】:

    这是一个关于这个话题的很好的讨论。对于非远程 EJB,Gavin King 建议使用 @Inject 而不是 @EJB。

    http://www.seamframework.org/107780.lace

    https://web.archive.org/web/20140812065624/http://www.seamframework.org/107780.lace

    Re:使用@EJB 或@Inject 进行注入?

    1. 2009 年 11 月 20:48 America/New_York |链接 Gavin King

    这个错误很奇怪,因为 EJB 本地引用应该总是 可序列化。可能是 glassfish 的虫子?

    基本上,@Inject 总是更好,因为:

    it is more typesafe,
    it supports @Alternatives, and
    it is aware of the scope of the injected object.
    

    我建议不要使用@EJB,除非声明对 远程 EJB。

    Re:使用@EJB 或@Inject 进行注入?

    1. 2009 年 11 月,17:42 America/New_York | Link Gavin King

      这是否意味着@EJB 对远程 EJB 更好?

    对于远程 EJB,我们不能像限定符那样声明元数据, @Alternative 等在 bean 类上,因为客户端根本不是 将有权访问该元数据。此外,一些额外的 必须指定本地案例不需要的元数据 (无论是全局 JNDI 名称)。所以所有这些东西都需要去 其他地方:即@Produces 声明。

    【讨论】:

    【解决方案4】:

    更新:此答案可能不正确或已过时。详情请看cmets。

    我从@Inject 切换到@EJB,因为@EJB 允许循环注射,而@Inject 会吐。

    详细信息:我需要 @PostConstruct 来调用 @Asynchronous 方法,但它会同步进行。进行异步调用的唯一方法是让原始调用另一个 bean 的方法并让它回调原始 bean 的方法。为此,每个 bean 都需要对另一个 bean 的引用——因此是循环的。 @Inject 未能完成此任务,而 @EJB 工作。

    【讨论】:

    • @MartijnBurger 我手头没有代码,也没有手头的 Java EE 环境。只需创建 2 个 Java 类并将 @Inject 它们放入彼此的公共字段中。如果这有效,那么我的答案是错误的。如果这不起作用,那么到目前为止我的回答是正确的。接下来将@Inject 更改为@EJB (并且可能自己注释类?我忘了。)。然后循环相互注入应该可以正常工作。这就是我从@Inject 切换到@EJB 的原因。希望这是有道理的。
    • 我创建了两个 pojo,并将 pojo 相互注入。在我的配置中正常工作(WildFly 8.2 = CDI 1.2)
    • 感谢@MartijnBurger,我会确认这一点,同时在我的回答中添加注意事项。
    • 不完全确定您想要实现什么,但这可能完全符合您的要求并且没有循环依赖。 tomee.apache.org/examples-trunk/async-postconstruct/README.html。此外,异步 CDI 事件可能是一种更简洁的方式(取决于要求)。
    【解决方案5】:

    Java EE 5 中已经存在注入,例如带有@Resource、@PersistentUnit 或@EJB 注释。 但它仅限于某些资源(数据源、EJB ......)和某些组件(Servlet、EJB、JSF 支持) 豆角,扁豆 。 . .)。借助 CDI,您几乎可以在任何地方注入任何东西,这要归功于 @Inject 注释。

    【讨论】:

      【解决方案6】:

      在使用@EJB 和@Inject 时,了解会话Bean 标识方面的区别也可能很有用。 根据规范,以下代码将始终为true

      @EJB Cart cart1;
      @EJB Cart cart2;
      … if (cart1.equals(cart2)) { // this test must return true ...}
      

      使用@Inject 代替@EJB 就不一样了。

      更多信息请参见stateless session beans identity

      【讨论】:

        【解决方案7】:

        将@EBJ 与EJB 一起使用。这是为了创建一个独立于接口类型(分层应用程序)的独立业务逻辑层。

        这(正确使用)允许独立于(多个)用户界面应用程序修改和部署业务逻辑,而不会失去可用性。

        【讨论】:

          猜你喜欢
          • 1970-01-01
          • 2018-09-05
          • 1970-01-01
          • 1970-01-01
          • 2015-10-16
          • 2023-03-06
          • 2013-02-20
          • 2011-07-31
          • 2010-12-23
          相关资源
          最近更新 更多