41

我大致知道这个构造的作用:它创建了一个 SomeType EJB 并将对象注入另一个 EJB。

 @EJB(name="name1")
 SomeType someVariable

现在我有一个这样开始的类:(我给出了所有类级别的注释,即使我认为只有@EJBs相关)

@Remote(SomeClass.class)
@Stateless(name="someName")
@EJBs({@EJB(name="name1",beanInterface=Type1.class),
       @EJB(name="name2",beanInterface=Type2.class)})
@TransactionAttribute(TransactionAttributeType.REQUIRED)
@TransactionManagement(TransactionManagementType.CONTAINER)
public class X extends Y{ 
  //code

s在这里做什么@EJB?他们可能从 JNDI 获取或创建“name1”...对象,但他们将结果放在哪里?我没有.lookup在附近看到任何电话,但代码库很大,所以我对此不太确定。

额外的问题:我认为这两个@Transaction注释只是重复默认值?

更新:此时多人声称这@EJBs是一个专有扩展。它不是。它是 java EE5 的核心部分。有关详细信息,请参阅JavaDoc。. 它只是单个@EJB注释的容器。

我相信声称这些 EJB 注释的每个人都会进行查找。我只想知道这个查找的结果会发生什么。

4

4 回答 4

42

@EJB注释(和@Resource,等)有@WebServiceRef两个目的:

  1. 它在组件命名空间中声明一个引用。例如,@EJB(name="myEJB")创建一个引用java:comp/env/myEJB。如果您对字段进行注释但未指定名称,则它会创建一个引用java:comp/env/com.example.MyClass/myField
  2. 如果在字段或 setter 方法上声明了注解,则容器在创建组件时执行注入。

解析引用的方式各不相同,与解析引用是针对lookup("java:comp/env/myEJB")注入还是由于注入无关:

  1. 如果使用 EE 6+,则该lookup属性需要 JNDI 查找来解析目标。
  2. 一些应用程序服务器支持mappedName,这被指定为特定于供应商。这通常通过执行查找来实现。
  3. 应用程序服务器在部署时支持绑定。这通常通过执行查找来实现。
  4. 如果没有提供其他绑定信息并且 bean 接口(beanInterface或字段类型)仅由应用程序中的单个 EJB 实现,那么 EJB 规范要求它回退到那个。
  5. 如果没有提供其他绑定信息并且#4 无法工作,一些应用程序服务器将尝试根据 ref 名称在服务器命名空间中执行查找(例如,java:comp/env/myEJB可能会导致myEJB在服务器命名空间中查找)。
于 2012-09-12T14:09:52.727 回答
2

根据此链接,基本上此注释使 EJB 能够相对于其上下文查找外部 EJB。通常,有更优雅的方法可以做到这一点。

于 2012-09-10T13:38:48.703 回答
2

Miljen Mikic 的回答让我对可能的答案有所了解。如果任何了解 JNDI 的人读到这篇文章,请告诉我这是否理智,因为我基本上在这里猜测。

基本上,有两种方法可以查看 JNDI 树:通过全局路径 (/some/proprietary/path/my/bean) 和通过程序的环境 (java:comp/env/my/bean)。这个想法是您创建从全局路径到本地环境的引用,然后从那里查找组件。

所以@Ejb(name="java:comp/env/my/bean",mappedName="/some/proprietary/path/my/bean") 将从java代码创建这个引用(没有描述符xml文件)。

这意味着 @Ejb(name="java:comp/env/my/bean") 本身就是无操作的:它将引用复制到自身上。它可能具有副作用,即您的应用程序服务器现在在编译时知道此引用是必需的,但仅此而已。

于 2012-09-12T07:51:32.113 回答
1

至于额外的问题:是的,关于事务的两个注释是重复默认值:默认 TransactionManagementType 是 CONTAINER (vs BEAN),并且 - default - TransactionAttributeType REQUIRED 只是说明如果在事务上下文中调用 bean,则事务将继续,否则将启动一个新事务(而不是像 REQUIRES_NEW 那样总是创建一个新的 tx)。这实际上并不像听起来那么简单。EJB 3.1 规范:

"13.3.7 Bean 方法的事务属性规范

具有容器管理事务划分的企业 bean 的 Bean 提供者可以为企业 bean 的方法指定事务属性。默认情况下,具有容器管理事务分界的 bean 的方法的事务属性值是 REQUIRED 事务属性,在这种情况下不需要显式指定事务属性。[...]"

于 2014-12-27T02:28:40.740 回答