【问题标题】:What does the @EJBs annotation do?@EJBs 注解有什么作用?
【发布时间】:2012-09-10 09:12:09
【问题描述】:

我大致知道这个构造的作用:它创建一个 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

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

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

更新: 多人此时声称@EJBs 是专有扩展。它不是。它是 java EE5 的核心部分。见the JavaDoc for details.。它只是单个 @EJB 注释的容器。

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

【问题讨论】:

  • 这很奇怪,我从未听说过@EJBs 和这样的用法。

标签: java jakarta-ee ejb


【解决方案1】:

@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 接口(@98​​7654330@ 或字段类型)仅由应用程序中的单个 EJB 实现,则 EJB 规范要求它回退到那个。
  5. 如果没有提供其他绑定信息并且#4 无法工作,一些应用程序服务器将尝试根据 ref 名称在服务器命名空间中执行查找(例如,java:comp/env/myEJB 可能会导致查找 myEJB 在服务器命名空间)。

【讨论】:

  • 我有一个 web 项目,jee 6,其中包含 ejbs,我不必用 @EJB 指定名称属性,一旦我将 ejbs 移动到单独的 ejb jar(仍然是同一只耳朵)weblogic 12.1.2告诉我“ejb-ref 没有 ejb-link 并且没有指定目标 Bean 的 JNDI 名称”
【解决方案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") 本身就是一个无操作:它将引用复制到自身上。您的应用程序服务器现在在编译时知道此引用是必需的,这可能会产生副作用,但仅此而已。

【讨论】:

    【解决方案3】:

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

    【讨论】:

    • EJB 是 Java EE5 标准的一部分。请参阅此处的 javadoc 作为证明。 docs.oracle.com/cd/E17802_01/products/products/ejb/…。这个 javadoc 很清楚:它只是收集了多个 EJB 注释。我认为您说这些 EJB 查找是正确的。我的问题的主要部分是:此查找的结果存储在哪里?
    • 感谢您指出这一点,不知道这包含在标准中,答案已更新。
    【解决方案4】:

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

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

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

    【讨论】:

      猜你喜欢
      • 2013-10-18
      • 1970-01-01
      • 2015-01-15
      • 1970-01-01
      • 2020-03-19
      • 2019-02-16
      • 2012-10-07
      • 1970-01-01
      • 2015-07-31
      相关资源
      最近更新 更多