Soll ich @EJB oder @Inject verwenden?

148

Ich habe diese Frage gefunden: Was ist der Unterschied zwischen @Inject und @EJB, aber ich bin nicht klüger geworden. Ich habe noch nie Java EE ausgeführt und habe auch keine Erfahrung mit der Abhängigkeitsinjektion, sodass ich nicht verstehe, was ich verwenden soll.

Ist @EJB eine alte Art zu injizieren? Wird die Injektion vom EJB-Container durchgeführt, wenn diese Annotation verwendet wird, während @Inject das neue CDI-Framework verwendet? Ist das der Unterschied und sollte ich @Inject anstelle von @EJB verwenden, wenn dies der Fall ist?

Lucky Luke
quelle

Antworten:

178

Das @EJBwird nur zur Injektion von EJBs verwendet und ist seit geraumer Zeit erhältlich. @Injectkann jede verwaltete Bean injizieren und ist Teil der neuen CDI-Spezifikation (seit Java EE 6).

In einfachen Fällen können Sie einfach ändern @EJBzu @Inject. In fortgeschrittenen Fällen (zB wenn Sie stark abhängig @EJB‚s Attribute wie beanName, lookupoder beanInterface) als verwenden , um @InjectSie müßte einen definieren @ProducerFeld oder eine Methode.

Diese Ressourcen können hilfreich sein, um die Unterschiede zwischen @EJBund zu verstehen @Producesund wie Sie das Beste daraus machen können:

Antonio Goncalves 'Blog:
CDI Teil I
CDI Teil II
CDI Teil III

JBoss Weld-Dokumentation:
CDI und das Java EE-Ökosystem

StackOverflow:
Injizieren Sie die @ EJB-Bean basierend auf den Bedingungen

Piotr Nowicki
quelle
4
Warum funktioniert @EJBdie zirkuläre Injektion (eine Singleton-Bohne und eine andere Bohne benötigen einen Verweis aufeinander)? (unter Bezugnahme auf meine Antwort unten - ich bin nicht sicher, ob ich das Richtige tue, indem ich zu wechsle @EJB)
Nekromant
2
weil Sie nicht die Implementierung injizieren, sondern einen Proxy, der sich in die Implementierung einfügt. Dadurch erhalten Sie die Vorteile der "späten Bindung" und anderer Containerfunktionen.
Ihn
33

@Injectkann jede Bohne injizieren, während @EJBnur EJBs injiziert werden können. Sie können entweder EJBs injizieren, aber ich würde es @Injectüberall bevorzugen .

Bozho
quelle
1
Was genau macht die Injektion, wenn wir @Inject verwenden? Der JavaEE-Container? Kann es POJOs injizieren?
Koray Tugay
3
mit CDI ist es der CDI-Container (im JavaEE-Container gebündelt)
Bozho
16

Update: Diese Antwort ist möglicherweise falsch oder veraltet. Einzelheiten entnehmen Sie bitte den Kommentaren.

Ich wechselte von @Injectzu, @EJBweil es @EJBeine kreisförmige Injektion erlaubt, während @InjectKotzen drauf sind.

Details: Ich musste @PostConstructeine @AsynchronousMethode aufrufen , dies geschah jedoch synchron. Die einzige Möglichkeit, den asynchronen Aufruf durchzuführen, bestand darin, dass der ursprüngliche Aufruf eine Methode einer anderen Bean und die Methode der ursprünglichen Bean zurückruft. Dazu brauchte jede Bohne einen Verweis auf die andere - also kreisförmig. @Injectfehlgeschlagen für diese Aufgabe während @EJBgearbeitet.

Nekromant
quelle
@MartijnBurger Ich habe weder den Code noch eine Java EE-Umgebung zur Hand. Erstellen Sie einfach 2 Java-Klassen und @Injectdiese in den öffentlichen Feldern des jeweils anderen. Wenn das funktioniert, ist meine Antwort falsch. Wenn das nicht funktioniert, ist meine Antwort bisher richtig. Als nächstes ändern Sie das @Injectzu @EJB(und kommentieren Sie möglicherweise die Klassen selbst? Ich vergesse.). Dann sollte die zyklische gegenseitige Injektion gut funktionieren. Deshalb habe ich von @Injectzu gewechselt @EJB. Hoffe das macht Sinn.
Nekromant
Ich habe zwei Pojos kreiert und die Pojos ineinander gespritzt. Funktioniert ohne Probleme in meiner Konfiguration (WildFly 8.2 = CDI 1.2)
Martijn Burger
1
Vielen Dank an @MartijnBurger, ich werde das bestätigen und in der Zwischenzeit meiner Antwort einen Hinweis zur Vorsicht hinzufügen.
Nekromant
Nicht genau sicher, was Sie erreichen wollten, aber dies macht wahrscheinlich genau das, was Sie wollten und ohne eine zirkuläre Abhängigkeit. tomee.apache.org/examples-trunk/async-postconstruct/README.html . Auch asynchrone CDI-Ereignisse könnten ein sauberer Weg sein (abhängig von den Anforderungen).
JanM
12

Hier ist eine gute Diskussion zum Thema. Gavin King empfiehlt @Inject over @EJB für nicht entfernte EJBs.

http://www.seamframework.org/107780.lace

oder

https://web.archive.org/web/20140812065624/http://www.seamframework.org/107780.lace

Betreff: Injizieren mit @EJB oder @Inject?

  1. Nov 2009, 20:48 America / New_York | Link Gavin King

Dieser Fehler ist sehr seltsam, da lokale EJB-Referenzen immer serialisierbar sein sollten. Bug in Glassfish vielleicht?

Grundsätzlich ist @Inject immer besser, da:

it is more typesafe,
it supports @Alternatives, and
it is aware of the scope of the injected object.

Ich empfehle gegen die Verwendung von @EJB, außer dass Verweise auf entfernte EJBs deklariert werden.

und

Betreff: Injizieren mit @EJB oder @Inject?

  1. November 2009, 17:42 Uhr America / New_York | Link Gavin King

    Bedeutet das, dass @EJB mit Remote-EJBs besser ist?

Für eine Remote-EJB können wir keine Metadaten wie Qualifizierer, @Alternative usw. für die Bean-Klasse deklarieren, da der Client einfach keinen Zugriff auf diese Metadaten hat. Darüber hinaus müssen einige zusätzliche Metadaten angegeben werden, die wir für den lokalen Fall nicht benötigen (globaler JNDI-Name von was auch immer). Das ganze Zeug muss also woanders hingehen: nämlich in der @ Product-Deklaration.

John Manko
quelle
1
Während dies theoretisch die Frage beantworten kann, wäre es vorzuziehen, die wesentlichen Teile der Antwort hier aufzunehmen und den Link als Referenz bereitzustellen. Auf diese Weise wäre diese Antwort auch jetzt noch wertvoll, wenn der Link tot ist.
Mifeet
4

Es kann auch nützlich sein, den Unterschied im Begriff der Session Bean-Identität zu verstehen, wenn @EJB und @Inject verwendet werden. Gemäß den Spezifikationen lautet der folgende Code immer true:

@EJB Cart cart1;
@EJB Cart cart2;
 if (cart1.equals(cart2)) { // this test must return true ...}

Bei Verwendung von @Inject anstelle von @EJB ist dies nicht dasselbe.

siehe auch stateless Session Beans Identität für weitere Infos

Ken
quelle
0

In Java EE 5 war beispielsweise bereits eine Injektion mit den Annotationen @Resource, @PersistentUnit oder @EJB vorhanden. Es war jedoch auf bestimmte Ressourcen (Datenquelle, EJB ...) und auf bestimmte Komponenten (Servlets, EJBs, JSF-Backing-Bean ...) beschränkt. Mit CDI können Sie dank der Annotation @Inject fast alles überall injizieren.

javierZanetti
quelle