How do I override the value supplied to a field annotated with @EJB?

别来无恙 提交于 2019-12-06 14:17:40

问题


Suppose I have a class like this:

@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
}

And elsewhere I have:

@Stateless
@Local({ Y.class })
public class YBean implements Y {}

@Stateless
@Local({ Y.class })
public class UnwantedYBean implements Y {}

Suppose now I want (in an XML descriptor, using the minimal amount of XML) to override or explicitly specify what gets placed in the y field in XBean.

This construct (in a META-INF/ejb-jar.xml file, of course) surprisingly (to me) does not work in 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>

I'd like to focus this question on the ejb-jar.xml snippet above, not on any container bugs or anything like that. Specifically: is the above snippet the correct and the smallest possible way to override what EJB gets injected into my XBean.y field?

Some notes:

  • Others have suggested that I need to put an <injection-target> stanza in there. Why would that be? The injection target is already specified by virtue of my using the @EJB annotation. I don't wish to override where the injection occurs, only what actually gets injected.

  • The EJB specification author herself also said that the <ejb-ref-name> should be simply y, not foo.XBean/y. This is despite the fact that the specification says (section 16.5.1.3):

The ejb-ref-name element specifies the EJB reference name: its value is the environment entry name used in the enterprise bean code [emphasis mine].

  • There is nowhere in the EJB specification that says what the default value of the name attribute is for the @EJB annotation (!), but we can infer that it is also the environment entry name.

    The spec gives an example in section 16.5.1.1:

package com.acme.example;
@Stateless public class ExampleBean implements Example {
  ...
  @EJB private ShoppingCart myCart;
  ...
}

...which is exactly equal to mine, and then says in the same section (this is as close as we'll get to discovering what the default value for @EJB's name attribute is):

The enterprise bean reference will have the name java:comp/env/com.acme.example.ExampleBean/myCart in the referencing bean’s naming context, where ExampleBean is the name of the class of the referencing bean and com.acme.example its package.

The "naming context" in that sentence is the java:comp/env/ part, so everything else is the name, so the default value of an unadorned @EJB annotation's name attribute is classname/fieldName. I don't see how this could be otherwise. This is also backed up by the table present in the GlassFish EJB FAQ.

Bottom line: what is wrong with my XML stanza cited above? Why does it not cause a proxied instance of YBean to be injected into my XBean's @EJB-annotated private Y y field?


回答1:


1.

Others have suggested that I need to put an <injection-target> stanza in there. Why would that be?

I agree with your interpretation that it's unnecessary. I'm most familiar with WebSphere Application Server, and its implementation also agrees with your interpretation.

2.

The EJB specification author herself also said that the should be simply y, not foo.XBean/y.

I disagree with that interpretation and agree with yours.

3.

There is nowhere in the EJB specification that says what the default value of the name attribute is for the @EJB annotation (!), but we can infer that it is also the environment entry name.

EJB 3.1 section 16.5.2.1 says:

The following rules apply to how a deployment descriptor entry may override an EJB annotation:

  • The relevant deployment descriptor entry is located based on the JNDI name used with the annotation (either defaulted or provided explicitly).


来源:https://stackoverflow.com/questions/17243775/how-do-i-override-the-value-supplied-to-a-field-annotated-with-ejb

标签
易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!