假设我有这样一个类:
@Stateless
@Local({ X.class })
public class XBean implements X {
@EJB // name() attribute should by spec default to "foo.XBean/y", but see below
private Y y; // Y is @Local
}
我在其他地方:
@Stateless
@Local({ Y.class })
public class YBean implements Y {}
@Stateless
@Local({ Y.class })
public class UnwantedYBean implements Y {}
假设现在我想(在XML描述符中,使用最少量的XML)覆盖或明确指定y
中XBean
字段中放置的内容。
这个结构(当然在META-INF/ejb-jar.xml
文件中)令人惊讶(对我来说)不在GlassFish 3.1.2.2中工作:
<ejb-jar>
<enterprise-beans>
<session>
<ejb-name>XBean</ejb-name>
<ejb-local-ref>
<ejb-ref-name>foo.XBean/y</ejb-ref-name>
<ejb-link>YBean</ejb-link>
</ejb-local-ref>
</session>
</enterprise-beans>
</ejb-jar>
我想将这个问题集中在上面的ejb-jar.xml
代码段上,而不是任何容器错误或类似内容。具体来说:上面的代码片段是覆盖EJB注入XBean.y
字段的正确和最小可能方式吗?
一些注意事项:
其他人建议我在那里放一个<injection-target>
节。那为什么会这样?注射目标已经通过我使用@EJB
注释来指定。我不希望覆盖注射的位置,只是实际注入的内容。
EJB规范作者自己也说<ejb-ref-name>
应该只是y
,而不是foo.XBean/y
。尽管规范说明(第16.5.1.3节):
ejb-ref-name元素指定EJB引用名称:其值是企业bean代码中使用的环境条目名称 [emphasis mine]。
EJB规范中没有任何地方说明name
注释(!)的@EJB
属性的默认值,但我们可以推断它也是环境条目名称。
规范在第16.5.1.1节中给出了一个例子:
package com.acme.example;
@Stateless public class ExampleBean implements Example {
...
@EJB private ShoppingCart myCart;
...
}
...这与我的完全相同,然后在同一部分中说明(这与我们发现@EJB
的{{1}}属性的默认值一样接近是):
企业bean引用在引用bean的命名上下文中将具有名称
name
,其中java:comp/env/com.acme.example.ExampleBean/myCart
是引用bean的类的名称,而ExampleBean
是其包。
该句子中的“命名上下文”是com.acme.example
部分,因此其他所有内容都是名称,因此未加修饰的java:comp/env/
注释的@EJB
属性的默认值为{{1 }}。我不明白这是怎么回事。这也由the GlassFish EJB FAQ中的表格支持。
结论:上面引用的我的XML节有什么问题?为什么它不会导致name
的代理实例被注入我的classname/fieldName
{ {1}} - 带注释的YBean
字段?
答案 0 :(得分:0)
1
其他人建议我需要放一个&lt;注射目标&gt;节 在那里。为什么会这样?
我同意你的解释,认为这是不必要的。我最熟悉WebSphere Application Server,它的实现也同意你的解释。
2
EJB规范的作者自己也说过了 应该只是y,而不是foo.XBean / y。
我不同意这种解释并同意你的意见。
3
EJB规范中没有任何地方说明默认值 name属性的值是@EJB注释(!),但我们可以 推断它也是环境条目名称。
EJB 3.1第16.5.2.1节说:
以下规则适用于部署描述符条目的方式 覆盖EJB注释:
- 相关部署描述符条目基于JNDI定位 与注释一起使用的名称(默认或提供 明确地)。