wake-up-neo.com

Was macht die @EJBs-Anmerkung?

Ich weiß ungefähr, was diese Konstruktion macht: Sie erstellt eine SomeType-EJB und fügt das Objekt in eine andere EJB ein.

 @EJB(name="name1")
 SomeType someVariable

Nun habe ich eine Klasse, die wie folgt beginnt: (Ich gebe alle Anmerkungen auf Klassenebene, obwohl ich denke, dass nur der @EJBs relevant ist).

@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

Was machen die @EJBs hier? Sie erhalten oder erstellen wahrscheinlich die "name1" ... Objekte von JNDI, aber wo legen sie das Ergebnis ab? Ich sehe keinen .lookup-Anruf in der Nähe, aber die Codebase ist riesig, daher bin ich mir nicht sehr sicher.

Bonusfrage: Ich nehme an, die beiden @Transaction-Anmerkungen wiederholen einfach die Standardwerte.

UPDATE: Mehrere Personen behaupteten an dieser Stelle, dass @EJBs eine proprietäre Erweiterung ist. Es ist nicht. Es ist ein Kernbestandteil von Java EE5. Siehe das JavaDoc für Details. . Es ist einfach ein Container für die einzelnen @EJB-Anmerkungen.

Ich glaube, dass jeder, der behauptet, dass diese EJB-Anmerkungen dies tun, eine Suche durchführt. Ich möchte nur wissen, was mit dem Ergebnis dieser Suche geschieht.

35
hyperman

Die Annotation @EJB (und @Resource, @WebServiceRef usw.) dient zwei Zwecken:

  1. Es deklariert einen Verweis im Komponentennamensraum. Zum Beispiel erstellt @EJB(name="myEJB") eine Referenz Java:comp/env/myEJB. Wenn Sie ein Feld mit Anmerkungen versehen und keinen Namen angeben, wird ein Verweis Java:comp/env/com.example.MyClass/myField erstellt.
  2. Wenn die Annotation für ein Feld oder eine Setter-Methode deklariert ist, führt der Container eine Injektion aus, wenn die Komponente erstellt wird.

Wie die Referenz aufgelöst wird, hängt davon ab, ob die Referenz für eine lookup("Java:comp/env/myEJB") oder aufgrund einer Injektion aufgelöst wird:

  1. Wenn EE 6+ verwendet wird, erfordert das lookup-Attribut eine JNDI-Suche, um das Ziel aufzulösen.
  2. Einige Anwendungsserver unterstützen mappedName, das herstellerspezifisch angegeben ist. Dies wird normalerweise durch Nachschlagen implementiert.
  3. Anwendungsserver unterstützen Bindungen zum Zeitpunkt der Bereitstellung. Dies wird normalerweise durch Nachschlagen implementiert.
  4. Wenn keine anderen Bindungsinformationen bereitgestellt werden und das Bean-Interface (beanInterface oder der Feldtyp) nur von einer einzelnen EJB in der Anwendung implementiert wird, muss die EJB-Spezifikation darauf zurückgreifen.
  5. Wenn keine anderen Bindungsinformationen angegeben werden und Nr. 4 nicht funktioniert, versuchen einige Anwendungsserver, anhand des Referenznamens eine Suche im Servernamensraum durchzuführen (z. B. kann Java:comp/env/myEJB im Servernamensraum nach myEJB suchen).
36
Brett Kail

Miljen Mikics Antwort gab mir eine Vorstellung von der möglichen Antwort. Wenn jemand, der sich mit JNDI auskennt, dies liest, sagen Sie mir bitte, ob dies vernünftig ist, da ich hier im Grunde nur vermute.

Grundsätzlich gibt es zwei Möglichkeiten, in den JNDI-Baum einzusehen: entweder über einen globalen Pfad (/ some/proprietary/path/my/bean) und über die Umgebung Ihres Programms (Java: comp/env/my/bean). Die Idee ist, dass Sie Verweise vom globalen Pfad zu Ihrer lokalen Umgebung erstellen und dann die Komponenten von dort suchen.

@Ejb (name = "Java: comp/env/my/bean", mappedName = "/ some/proprietary/path/my/bean") erstellt diese Referenz also aus Java-Code (ohne XML-Deskriptordatei).

Dies bedeutet, dass @Ejb (name = "Java: comp/env/my/bean") für sich genommen ein No-Op ist: Es kopiert einen Verweis auf sich selbst. Es kann als Nebeneffekt die Tatsache haben, dass Ihr Anwendungsserver jetzt zur Kompilierzeit weiß, dass diese Referenz erforderlich ist, aber das ist es.

2
hyperman

Gemäß diesem link ermöglicht diese Anmerkung grundsätzlich, dass EJB externe EJBs relativ zu ihrem Kontext nachschlagen kann. Normalerweise gibt es elegantere Möglichkeiten, dies zu tun.

1
Miljen Mikic

Was die Bonusfrage betrifft: Ja, die beiden Anmerkungen zu Transaktionen wiederholen die Standardwerte: Der Standard-TransactionManagementType ist CONTAINER (vs BEAN) und der - default - TransactionAttributeType REQUIRED besagt lediglich, dass die Transaktion in einem Transaktionskontext fortgesetzt wird. Andernfalls wird eine neue Transaktion initiiert (im Gegensatz zu REQUIRES_NEW, das immer einen neuen Sender erstellt). Das ist eigentlich nicht so banal wie es klingt. die EJB 3.1-Spezifikation: 

"13.3.7 Spezifikation der Transaktionsattribute für die Methoden eines Beans

Der Bean-Provider einer Enterprise-Bean mit vom Container verwalteter Transaktionsabgrenzung kann Die Transaktionsattribute für die Methoden der Enterprise-Bean angeben. Standardmäßig ist der Wert des Transaktionsattributs Für eine Methode einer Bean mit durch Container verwalteter Transaktionsabgrenzung das REQUIRED -Transaktionsattribut. In diesem Fall muss das Transaktionsattribut nicht explizit angegeben werden. [. ..] "

1
William Adams