我应该使用@EJB还是@Inject


148

我发现了这个问题:@Inject和@EJB有什么区别,但是我没有变得更明智。我以前没有做过Java EE,也没有依赖注入的经验,所以我不明白应该使用什么?

@EJB是旧的注入方式吗?使用@Inject时使用此批注时,EJB容器是否通过新的CDI框架进行注入?有区别吗?如果是这种情况,我应该使用@Inject而不是@EJB吗?

Answers:


178

@EJB用于注入EJB的仅适用于现在相当一段时间。@Inject可以注入任何托管bean,并且是新的CDI规范的一部分(自Java EE 6起)。

在简单的情况下,您只需更改@EJB为即可@Inject。在更先进的情况下(例如,当您在很大程度上依赖@EJB的属性,如beanNamelookupbeanInterface)不是为了使用@Inject,你需要定义一个@Producer字段或方法。

这些资源可能有助于理解之间的差异@EJB以及@Produces如何获得他们最好的:

Antonio Goncalves的博客:
CDI第一部分
CDI第二部分
CDI第三部分

JBoss Weld文档:
CDI和Java EE生态系统

StackOverflow:
根据条件注入@EJB bean


4
为什么@EJB对循环注入有效(一个单例bean和另一个bean需要互相引用)?(请参考下面的答案-我不确定是否通过切换到来做正确的事情@EJB
死灵法师

2
因为您不是在注入实现,而是在实现上插入了一个代理。因此,您可以获得“后期绑定”和其他容器功能的优势。

33

@Inject可以注入任何bean,而@EJB只能注入EJB。您可以使用任何一种来注入EJB,但是我更喜欢@Inject在任何地方。


1
当我们使用@Inject时,究竟是什么使注入?JavaEE容器?可以注入POJO吗?
Koray Tugay 2013年

3
与CDI一起使用的是CDI容器(捆绑在JavaEE容器中)
Bozho

16

更新:此答案可能不正确或已过期。请查看评论以获取详细信息。

我从切换到@Inject@EJB是因为@EJB允许循环注射而@Inject对其进行呕吐。

详细信息:我需要@PostConstruct调用一个@Asynchronous方法,但是它将同步进行。进行异步调用的唯一方法是让原始调用另一个bean的方法,然后让它回调原始bean的方法。为此,每个Bean需要互相引用-从而是循环的。@Inject因这项工作而失败,但是@EJB工作了。


@MartijnBurger我没有方便的代码,也没有Java EE环境。只需创建2个Java类,@Inject并将它们放入彼此的公共字段即可。如果可行,那么我的答案是错误的。如果那不起作用,那么到目前为止我的回答是正确的。接下来,将其更改@Inject@EJB(并可能对类本身进行注释?我忘记了。)。然后,循环互注入应该可以正常工作。这就是为什么我从切换@Inject@EJB。希望这是有道理的。
necromancer

我创建了两个pojo,然后将pojo相互注入。可以在我的配置中正常工作(WildFly 8.2 = CDI 1.2)
Martijn Burger

1
感谢@MartijnBurger,我将确认这一点,同时在我的回答中加注注意事项。
necromancer 2015年

不确定要实现的目标,但这可能完全符合您的目标,并且没有循环依赖。tomee.apache.org/examples-trunk/async-postconstruct/README.html。同样,异步CDI事件也可以是一种更干净的方式(取决于需求)。
2015年

12

这是关于该主题的精彩讨论。对于非远程EJB,Gavin King建议在@EJB上使用@Inject。

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

要么

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

回复:使用@EJB或@Inject注入?

  1. 2009年11月,20:48美国/纽约| 链接加文·金

该错误非常奇怪,因为EJB本地引用应始终可序列化。也许是玻璃鱼里的虫子?

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

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

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

回复:使用@EJB或@Inject注入?

  1. 2009年11月,17:42美国/纽约| 链接加文·金

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

对于远程EJB,我们无法在Bean类上声明诸如限定符,@ Alternative等的元数据,因为客户端根本无法访问该元数据。此外,必须指定一些对于本地情况不需要的其他元数据(全局JNDI名称)。所以所有这些东西都需要放在其他地方:@Produces声明。


1
虽然从理论上讲这可以回答问题,但最好在此处包括答案的基本部分,并提供链接以供参考。这样,即使当链接断开时,此答案也仍然很有价值。
Mifeet


4

理解使用@EJB和@Inject时会话Bean身份术语的不同可能也很有用。根据规范,以下代码将始终为true

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

使用@Inject而不是@EJB是不一样的。

另请参见无状态会话Bean身份以获取更多信息


0

例如,Java EE 5中已经存在带有@ Resource,@ PersistentUnit或@EJB批注的注入。但是它仅限于某些资源(数据源,EJB ...)和某些组件(Servlet,EJB,JSF支持bean ...)。使用CDI,由于@Inject批注,您几乎可以在任何地方注入任何东西。

By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.