Wie vergleichen sich CDI und EJB? interagieren?

106

Es fällt mir schwer zu verstehen, wie die beiden interagieren und wo die Grenze zwischen ihnen liegt. Überlappen sie sich? Gibt es Redundanzen zwischen ihnen?

Ich weiß, dass mit beiden Anmerkungen verbunden sind, aber ich konnte für beide keine vollständige Liste mit kurzen Beschreibungen finden. Ich bin mir nicht sicher, ob dies helfen würde, zu klären, wie sie sich unterscheiden oder wo sie sich überschneiden.

Wirklich nur verwirrt. Ich (glaube ich) verstehe EJB ziemlich gut, ich denke, es fällt mir schwer, genau zu verstehen, was CDI auf den Tisch bringt und wie es das ersetzt oder verbessert, was EJB bereits bietet.

Tim
quelle
3
Diese Frage steht bei Googles Suche nach "EJB CDI-Unterschieden" ganz oben, aber ich fand die Antwort unter stackoverflow.com/questions/13487987/… klarer
matt freake

Antworten:

50

CDI: Es geht um Abhängigkeitsinjektion. Dies bedeutet, dass Sie die Schnittstellenimplementierung überall einfügen können. Dieses Objekt kann alles sein, es kann nicht mit EJB verwandt sein. Hier ist ein Beispiel, wie ein Zufallsgenerator mit CDI injiziert wird. Es gibt nichts über EJB. Sie werden CDI verwenden, wenn Sie Nicht-EJB-Dienste, verschiedene Implementierungen oder Algorithmen einfügen möchten (sodass Sie dort überhaupt kein EJB benötigen).
EJB: Sie verstehen, und wahrscheinlich sind Sie durch @EJBAnmerkungen verwirrt - es ermöglicht Ihnen, die Implementierung in Ihren Service oder was auch immer einzufügen. Die Hauptidee ist, dass die Klasse, in die Sie injizieren, vom EJB-Container verwaltet werden sollte. Scheint, dass CDI versteht, was EJB ist. Auf einem Java EE 6-kompatiblen Server können Sie also in Ihrem Servlet beide schreiben

@EJB EJBService ejbService;

und

@Inject EJBService ejbService;

Das kann Sie verwirren, aber das ist wahrscheinlich das einzige, was die Brücke zwischen EJB und CDI ist.

Wenn wir über CDI sprechen, können Sie andere Objekte in von CDI verwaltete Klassen einfügen (sie sollten nur von CDI-fähigen Frameworks erstellt werden).

Was CDI sonst noch bietet ... Zum Beispiel verwenden Sie Struts 2 als MVC-Framework (nur ein Beispiel), und Sie sind hier eingeschränkt, selbst wenn Sie EJB 3.1 verwenden - Sie können keine @EJBAnnotation in der Struts-Aktion verwenden, sie wird nicht vom Container verwaltet. Wenn Sie jedoch das Struts2-CDI-Plugin hinzufügen, können Sie dort @InjectAnmerkungen für dasselbe schreiben (sodass keine weitere JNDI-Suche erforderlich ist). Auf diese Weise wird die EJB-Leistung verbessert, aber wie bereits erwähnt, was Sie mit CDI injizieren - es spielt keine Rolle, ob es mit EJB zusammenhängt oder nicht, und das ist seine Leistung.

PS. aktualisierter Link zum Beispiel

Maxym
quelle
Sind @EJB und @Inject wirklich funktional gleichwertig? Ich denke, es war die Überschneidung der Injektionsmethoden zwischen CDI und einigen anderen Java EE-Akronymsuppen, die mich verwirrte. Mehr Lektüre scheint darauf hinzudeuten, dass Hoffnung besteht, die Anmerkungen auszurichten.
Tim
@Maxym Wie können Sie bei Verwendung von @ Inject sicherstellen, dass @ Stateless oder eine andere serverseitige Komponente von EJB weiterhin die vom Container angebotenen Funktionen wie Pooling oder Parallelität verwendet? Ich hoffe das wird von CDI nicht angeboten oder?
Bala
1
@ Bala: CDI bietet kein Pooling an ... schauen Sie sich CDI mit oder ohne EJB3.1 an , hoffen Sie, dass es Ihre Frage beantwortet ..
Maxym
@KorayTugay: CDI ist eine Java EE-Funktion, daher verfügt jeder Java EE 6-kompatible Server über diese Funktion (Glassfish 3.0.1+ ist nicht falsch, JBoss 6+ usw.). Sie können sich JBoss Weld ansehen, eine Referenz-CDI-Implementierung, die Sie verwenden kann zum Beispiel in Tomcat verwenden ...
Maxym
191

Es ist derzeit in der Tat etwas verwirrend, da es in Java EE jetzt mehrere Komponentenmodelle gibt. Sie sind CDI , EJB3 und JSF Managed Beans .

CDI ist das neue Kind auf dem Block. CDI Bohnen verfügen dependency injection, scopingund ein event bus. CDI-Bohnen sind in Bezug auf Injektion und Scoping am flexibelsten. Der Eventbus ist sehr leicht und auch für die einfachsten Webanwendungen sehr gut geeignet. Darüber hinaus bietet CDI eine sehr erweiterte Funktion namens " portable extensionsPlug-In " , eine Art Plug-In-Mechanismus, mit dem Anbieter Java EE zusätzliche Funktionen zur Verfügung stellen können, die für alle Implementierungen (Glassfish, JBoss AS, Websphere usw.) verfügbar sind. .

EJB3- Beans wurden aus dem alten EJB2-Komponentenmodell * nachgerüstet und waren die ersten Beans in Java EE, die über eine Anmerkung mit Beans verwaltet wurden. EJB3 Bohnen verfügen dependency injection, declarative transactions, declarative security, pooling, concurrency control, asynchronous executionund remoting.

Die Abhängigkeitsinjektion in EJB3-Beans ist nicht so flexibel wie in CDI-Beans, und EJB3-Beans haben kein Konzept für das Scoping. EJB3-Beans sind jedoch standardmäßig transaktional und gepoolt ** , zwei sehr nützliche Dinge, die CDI in der Domäne von EJB3 belassen hat. Die anderen genannten Artikel sind auch nicht in CDI verfügbar. EJB3 hat zwar keinen eigenen Ereignisbus, aber einen speziellen Bean-Typ zum Abhören von Nachrichten. die nachrichtengesteuerte Bean. Dies kann verwendet werden, um Nachrichten vom Java Messaging System oder von jedem anderen System mit einem JCA-Ressourcenadapter zu empfangen. Die Verwendung von Messaging für einfache Ereignisse ist weitaus schwerer als der CDI-Ereignisbus, und EJB3 definiert nur einen Listener, keine Produzenten-API.

JSF Managed Beans gibt es in Java EE seit der Aufnahme von JSF. Sie verfügen auch über dependency injectionund scoping. JSF Managed Beans führte das Konzept des deklarativen Scoping ein. Ursprünglich waren die Bereiche eher begrenzt und in derselben Version von Java EE, in der EJB3-Beans bereits über Anmerkungen deklariert werden konnten, mussten JSF Managed Beans noch in XML deklariert werden. Die aktuelle Version von JSF Managed Beans wird schließlich auch über eine Anmerkung deklariert, und die Bereiche werden um einen Ansichtsbereich und die Möglichkeit zum Erstellen benutzerdefinierter Bereiche erweitert. Der Ansichtsbereich, in dem Daten zwischen Anforderungen auf derselben Seite gespeichert werden, ist eine einzigartige Funktion von JSF Managed Beans.

Abgesehen vom Ansichtsbereich gibt es in Java EE 6 nur noch sehr wenig für JSF Managed Beans. Der fehlende Ansichtsbereich in CDI ist bedauerlich, da CDI sonst ein perfekter Super-Satz dessen gewesen wäre, was JSF Managed Beans bieten. Update : In Java EE 7 / JSF 2.2 wurde ein CDI-kompatibles @ViewScoped hinzugefügt, wodurch CDI in der Tat das perfekte Super-Set ist. Update 2 : In JSF2.3 wurden die von JSF verwalteten Beans zugunsten von von CDI verwalteten Beans veraltet.

Bei EJB3 und CDI ist die Situation nicht so eindeutig. Das EJB3-Komponentenmodell und die API bieten viele Dienste, die CDI nicht bietet. Daher kann EJB3 normalerweise nicht durch CDI ersetzt werden. Auf der anderen Seite kann CDI in Kombination mit EJB3 verwendet werden - z. B. um EJBs eine Bereichsunterstützung hinzuzufügen.

Reza Rahman, Mitglied der Expertengruppe und Implementierer einer CDI-Implementierung namens CanDI, hat häufig angedeutet, dass die mit dem EJB3-Komponentenmodell verbundenen Dienste als eine Reihe von CDI-Anmerkungen nachgerüstet werden können. In diesem Fall könnten alle verwalteten Beans in Java EE zu CDI-Beans werden. Dies bedeutet nicht, dass EJB3 verschwindet oder veraltet ist, sondern nur, dass seine Funktionalität über CDI anstatt über EJBs eigene Anmerkungen wie @Stateless und @EJB verfügbar gemacht wird.

Aktualisieren

David Blevins von TomEE und OpenEJB erklärt die Unterschiede und Ähnlichkeiten zwischen CDI und EJB sehr gut in seinem Blog: CDI, wann die EJBs ausbrechen sollen

* Obwohl es sich nur um eine Erhöhung der Versionsnummer handelt, waren EJB3-Beans größtenteils eine völlig andere Art von Beans: ein einfaches Pojo, das durch Anwenden einer einfachen einzelnen Anmerkung zu einer "verwalteten Bean" wird, im Vergleich zu dem Modell in EJB2, in dem ein Schwergewicht und Für jede Bean war ein übermäßig ausführlicher XML-Bereitstellungsdeskriptor erforderlich. Außerdem musste die Bean verschiedene extrem schwere und größtenteils bedeutungslose Komponentenschnittstellen implementieren.

** Zustandslose Session-Beans werden normalerweise gepoolt, Stateful-Session-Beans normalerweise nicht (aber sie können es sein). Für beide Typen ist das Pooling daher optional, und die EJB-Spezifikation schreibt dies in keiner Weise vor.

Arjan Tijms
quelle
3
Ich bin ein bisschen verwirrt von Ihren Aussagen, dass "EJB3-Beans kein Scoping-Konzept haben" und dass "EJB3 jedoch keinen eigenen Event-Bus hat". Wie passt das mit David Blevin der Behauptung , dass „EJBs sind CDI Bohnen und deshalb haben alle Vorteile der CDI“? Hat sich in dieser Hinsicht etwas geändert, als Sie Ihre Antwort geschrieben haben und als David seinen Blogeintrag geschrieben hat?
Chris
5
Aufgrund des vielleicht etwas verwirrenden Konzepts gibt es eigentlich nicht wirklich "CDI-Beans", aber es gibt Dienste, die auf verwaltete Beans angewendet werden. Aus Gründen der Diskussion bezeichnen die Leute (und ich selbst) sie sowieso als "CDI-Beans". Vor CDI hatten EJB-Beans keinen expliziten Geltungsbereich. Wie David erklärt, ist Stateful implizit jeder Geltungsbereich (und damit insbesondere kein Geltungsbereich) Wenn CDI verfügbar ist, können EJB-Beans die von CDI bereitgestellten Bereiche nutzen. Ohne die CDI-Spezifikation gibt es also keine expliziten Bereiche, wenn nur die EJB-Spezifikation betrachtet wird.
Arjan Tijms
1
Können Sie näher erläutern, was Sie unter "Es gibt Dienste für verwaltete Beans" verstehen? Bedeutet das, dass es eigentlich keine CDI-Bean gibt? Es sind nur einige, die zusätzliche Funktionen für eine POJO - EJB - oder eine JSF Managed Bean bieten. Möchten Sie Inject Annotation in einer JSF Managed Bean verwenden?
Koray Tugay
3
@Chris Um aus Sicht der EJB-Spezifikation weiter zu verdeutlichen, haben wir von Anfang an die bewusste Entscheidung getroffen, dass EJB-Implementierungen 100% der auf EJBs festgelegten CDI-Funktionen unterstützen müssen. Jeder Aspekt von CDI funktioniert mit EJBs, mit Ausnahme der Bereiche, die wir nur auf Stateful Beans beschränken mussten.
David Blevins
1
Beachten Sie, dass JSF 2.2 jetzt javax.faces.view.ViewScoped bereitstellt, eine CDI-Erweiterung, die im Wesentlichen ein Port des JSF-Ansichtsbereichs für CDI ist. Damit ist CDI ein vollständiger Ersatz für JSF Managed Beans.
jdessey
-1

Albert Einstein: If you can't explain it simply, you don't understand it well enough

Ejbs und CDI sind ziemlich einfach zu verstehen.

Ejbs:

  1. Wird immer durch Bereichsqualifizierer kommentiert, z. B. @Stateless, @Stateful, @Request usw.
  2. Die Instanzen von Ejbs werden vom Java EE-Framework gesteuert und zusammengefasst. Es ist die Pflicht des EE-Rahmens, die Instanzen für den Verbraucher bereitzustellen.

@Stateless

 public class CarMaker(){
    public void createCar(Specification specs){
        Car car = new Car(specs);
    }
}

Der CarMaker ist mit einem bestimmten Ejbs-Bereich versehen, daher ist es Ejb

CDI:

  1. Instanzen, die nicht vollständig vom EE-Framework verwaltet werden, müssen von Ihnen selbst erstellt werden.
  2. Es ist immer abhängig. Lassen Sie mich "Abhängig" anhand eines Beispiels erklären:

    class Specification { private String color; private String model; //- Getter and Setter }

Die SpecificationKlasse ist CDI, da sie nicht mit Ejb-Bereichen versehen ist und dies auch durch Ihren Code und nicht durch das EE-Framework initialisiert werden muss. Ein Punkt, der hier zu beachten ist, ist, dass die SpecificationKlasse standardmäßig mit @DependentAnmerkungen versehen ist, da wir sie nicht mit Anmerkungen versehen haben.

@Dependent  <- By default added 
class Specification { ... }

Further reading: Sie müssen mehr zwischen Ejbs-Bereichsanmerkung und CDI-Bereichsanmerkung lernen, um das Konzept weiter zu verdeutlichen

HAT
quelle
Einstein sagte auch: "Alles sollte so einfach wie möglich gemacht werden, aber nicht einfacher" Sie können (sollten) hier "gemacht" durch "erklärt" ersetzen.
Kukeltje