我有一个.ear
文件,里面有几十个EJB jar文件。
每个EJB jar文件中都包含数十个EJB。
每个EJB都有@EJB
个引用,没有其他信息(没有name
属性等)。
目前一切正常工作:恰好,对于任何给定的@EJB
- 注释注入目标,只有一个具体的EJB存在于.ear
文件中以填充插槽。 / p>
我出于各种原因需要引入一些包含EJB的EJB jar文件,这些文件也可以填充其中一些插槽。
因此,我需要告诉我的Java EE容器哪个EJB注入哪个存在冲突的插槽。
我熟悉ejb-jar.xml
deployment descriptor mechanism for overriding EJB references,但如果这是我唯一的办法,我正在考虑改变这些条目。
我在application.xml
schema version 6注意到那里也支持<ejb-local-ref>
元素,这是我想要的抽象方式。但我无法弄清楚如何利用这些元素来做我想做的事。
在一些抽象的完美世界中,我想以某种方式在一个地方说“嘿,Java EE容器,当你看到一个@EJB
- 注释字段时这样:
@EJB
SomeType bean;
...请将beanName
为fred
的EJB注入其中。在这个应用程序的任何地方。“我该怎么做?
答案 0 :(得分:4)
没有标准的方法可以做到这一点,据我所知,没有通用的特定于供应商的方法。
这是我试图在EJB 3.1中为EJB和JPA引用的内容:如果注入点使用默认规则,因为只有一个SomeType
bean,但是某天某一秒{{1} } bean被添加......直言不讳,你被软管:) SomeType
和@PersistenceContext
refs也存在这个问题。这个想法是/有一些“这是标准部署描述符中的@PersistenceUnit
选项的默认impl,并在这些情况下保释人员。
我们仍应将此纳入规范。如果这是你的问题,我会重新发布该提议,如果你能跟进关于这对你来说有多少噩梦的信息,我几乎可以保证我们将为EJB.next修复这个问题。
目前,一种可能的方法是使用标志SomeType
在TomEE中临时部署此耳朵。 TomEE / OpenEJB实际上将为您的应用程序提供所有有效的部署描述符。如果您的应用程序与您声明的一样大,可以为您节省几个小时或几天。在内部我们1)读入部署描述符,2)使用注释来“填写”部署描述符。结果是我们有一个树,它是每个EJB模块的规范“元数据”集。设置openejb.descriptors.output=true
标志后,我们会将每个ejb-jar.xml文件写入磁盘并记录该位置。
掌握了ejb-jar.xml文件后,您可以随意修改并返回GlassFish,也许还有更好的运气。
就如何在Java EE中实际管理它而言,您必须了解如何成功覆盖引用。在注释引用如何转换为xml时,需要了解一些关键信息。目标是有1个参考而不是N.
当您的引用未命名时:
openejb.descriptors.output=true
...有一个固定的规则,默认名称必须是package org.some.awesome.code;
public class Foo {
@EJB
SomeType orange;
。类名和包成为名称的一部分,以便在覆盖时为您提供最精细的控制。以下xml将覆盖此引用:
org.some.awesome.code.Foo/orange
此引用现在将链接到类型<ejb-local-ref>
<ejb-ref-name>org.some.awesome.code.Foo/orange</ejb-ref-name>
<local>org.some.awesome.code.SomeType</local>
<ejb-link>Fred</ejb-link>
</ejb-local-ref>
的EJB,其beanName为'Fred'。
这样做的缺点是,如果您有100个像这样的引用并且想要全部更改它们,则需要100个xml声明来执行此操作。
没有办法摆脱这个不涉及更改代码的问题 - 这就是我的“使用它作为默认”提案有价值的地方,它允许一个xml更改来处理所有100个没有代码更改的情况。这很简单,因为能够说“当我在我的代码中不具体时,我的意思是通过部署描述符使用X”。
也许只使用类型在xml中声明覆盖是合法的,如下所示:
SomeType
如上所述,目前这不合法。
有一些代码更改方法可用,但其中一种方法是为每个<ejb-local-ref>
<local>org.some.awesome.code.SomeType</local>
<ejb-link>Fred</ejb-link>
</ejb-local-ref>
引用相同的名称。那么你最终只会得到1个参考而不是N.
@EJB
这里明确给出了引用的名称,所以在xml中覆盖它可以更简单地完成如下:
package org.some.awesome.code;
public class Foo {
@EJB(name "purple")
SomeType orange;
如果有100个<ejb-local-ref>
<ejb-ref-name>purple</ejb-ref-name>
<local>org.some.awesome.code.SomeType</local>
<ejb-link>Fred</ejb-link>
</ejb-local-ref>
引用,则所有这些引用都会被上述声明覆盖。
简短回答,目前还没有简单的方法。您正在寻找广泛的xml或广泛的代码更改。
从长远来看,我们可以有希望改进规范的这一部分,以便人们在超出默认匹配规则时不会受到惩罚。
答案 1 :(得分:0)
我目前正在解决同样的问题。我正在研究覆盖JNDI上下文的可能性,因此它提供了除标准实例之外的其他实例。您只需将系统属性 java.naming.factory.initial (例如,在jndi.properties中)设置为您的实现,并将实现放在根类路径上。然后在工厂中,您可以使用重写的查找方法创建自己的上下文版本。听起来很简单,但我好好想好几天。