我大致知道这个构造的作用:它创建一个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注释的每个人都会进行查找。我只是想知道这次查找结果会发生什么。
@EJB
注释(和@Resource
,@WebServiceRef
等)有两个目的:
@EJB(name="myEJB")
创建了一个参考java:comp/env/myEJB
。如果您注释一个字段而没有指定名称,那么它会创建一个引用java:comp/env/com.example.MyClass/myField
。解析参考的方式各不相同,无论参考是针对lookup("java:comp/env/myEJB")
解决还是由于注射:
lookup
属性需要JNDI查找才能解析目标。mappedName
,指定为特定于供应商。这通常通过执行查找来实现。beanInterface
或字段类型)仅由应用程序中的单个EJB实现,那么EJB规范要求它回退到那个。java:comp/env/myEJB
可能导致在服务器命名空间中查找myEJB
)。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”)本身就是一个无操作:它将引用复制到自身。它可能会产生副作用,因为您的应用程序服务器现在在编译时知道此引用是必需的,但这就是它。
根据这个link,基本上这个注释使EJB能够相对于其上下文查找外部EJB。通常,有更优雅的方法来做到这一点。
至于奖金问题:是的,关于交易的两个注释是重复默认值:默认的TransactionManagementType是CONTAINER(vs BEAN), - default - TransactionAttributeType REQUIRED只是说明如果在事务上下文中调用bean,则事务继续,否则将启动一个新的交易(相反,例如REQUIRES_NEW将始终创建一个新的tx)。这实际上并不像听起来那么简单。 EJB 3.1规范:
“13.3.7 Bean方法的事务属性的规范
具有容器管理的事务划分的企业bean的Bean Provider可以指定企业bean的方法的事务属性。默认情况下,具有容器管理的事务划分的bean的方法的transaction属性的值是REQUIRED事务属性,在这种情况下不需要显式指定事务属性。[...]“