Ja, Sie können sowohl CDI als auch EJB frei mischen und einige großartige Ergebnisse erzielen. Es hört sich so an, als würden Sie @WebService
und verwenden @Schedule
, was gute Gründe sind, EJB zum Mix hinzuzufügen.
Es gibt da draußen viel Verwirrung, daher hier einige allgemeine Informationen zu EJB und CDI, die sich auf beide zusammen beziehen.
EJB> = CDI
Beachten Sie, dass EJBs sind CDI Bohnen und haben deshalb alle die Vorteile von CDI. Das Gegenteil ist (noch) nicht der Fall. Gewöhnen Sie sich also definitiv nicht an, "EJB vs CDI" zu denken, da diese Logik wirklich zu "EJB + CDI vs CDI" führt, was eine seltsame Gleichung ist.
In zukünftigen Versionen von Java EE werden wir sie weiterhin ausrichten. Was Mittel Ausrichten Personen erlauben, zu tun , was sie bereits tun können, nur ohne die @Stateful
, @Stateless
oder @Singleton
Anmerkung an der Spitze.
EJB und CDI in Implementierungsbedingungen
Letztendlich haben EJB und CDI das gleiche grundlegende Design wie Proxy-Komponenten. Wenn Sie einen Verweis auf eine EJB- oder CDI-Bean erhalten, handelt es sich nicht um die echte Bean. Vielmehr ist das Objekt, das Sie erhalten, eine Fälschung (ein Proxy). Wenn Sie eine Methode für dieses gefälschte Objekt aufrufen, geht der Anruf an den Container, der den Anruf über Abfangjäger, Dekorateure usw. sendet und sich um alle Transaktionen oder Sicherheitsüberprüfungen kümmert. Sobald alles erledigt ist, geht der Anruf schließlich an das reale Objekt und das Ergebnis wird über den Proxy an den Anrufer zurückgegeben.
Der Unterschied besteht nur darin, wie das aufzurufende Objekt aufgelöst wird. Mit "gelöst" meinen wir einfach, wo und wie der Container nach der realen Instanz sucht, die aufgerufen werden soll.
In CDI sieht der Container in einem "Bereich" aus, bei dem es sich im Grunde um eine Hashmap handelt, die für einen bestimmten Zeitraum gültig ist (pro Anforderung @RequestScoped
, pro HTTP-Sitzung @SessionScoped
, pro Anwendung @ApplicationScoped
, JSF-Konversation @ConversationScoped
oder gemäß Ihrer benutzerdefinierten Bereichsimplementierung).
In EJB untersucht der Container auch eine Hashmap, wenn die Bean vom Typ ist @Stateful
. Eine @Stateful
Bean kann auch eine der oben genannten Bereichsanmerkungen verwenden, wodurch sie mit allen anderen Bohnen im Bereich lebt und stirbt. In EJB @Stateful
ist im Wesentlichen die "jede Scoped" Bohne. Dies @Stateless
ist im Grunde ein Instanzpool - Sie erhalten eine Instanz aus dem Pool für die Dauer eines Aufrufs. Das @Singleton
ist im Wesentlichen@ApplicationScoped
Grundsätzlich sollte alles, was Sie mit einer "EJB" -Bohne tun können, mit einer "CDI" -Bohne möglich sein. Unter der Decke ist es furchtbar schwer, sie auseinander zu halten. Alle Installationen sind gleich, mit Ausnahme der Art und Weise, wie Instanzen aufgelöst werden.
Sie sind derzeit nicht dieselben in Bezug auf die Dienste, die der Container bei diesem Proxy anbietet, aber wie gesagt, wir arbeiten auf der Java EE-Spezifikationsebene daran.
Leistungshinweis
Ignorieren Sie alle "leichten" oder "schweren" mentalen Bilder, die Sie möglicherweise haben. Das ist alles Marketing. Sie haben größtenteils das gleiche interne Design. Die Auflösung von CDI-Instanzen ist möglicherweise etwas komplexer, da sie etwas dynamischer und kontextbezogener ist. Die Auflösung der EJB-Instanz ist im Vergleich ziemlich statisch, dumm und einfach.
Ich kann Ihnen aus Sicht der Implementierung in TomEE sagen, dass zwischen dem Aufrufen eines EJB und dem Aufrufen einer CDI-Bean etwa kein Leistungsunterschied besteht.
Standardmäßig POJOs, dann CDI, dann EJB
Verwenden Sie CDI oder EJB natürlich nicht, wenn es keinen Nutzen gibt. Werfen Sie CDI ein, wenn Sie Injektionen, Ereignisse, Abfangjäger, Dekorateure, Lebenszyklus-Tracking und ähnliches wünschen. Das ist die meiste Zeit.
Abgesehen von diesen Grundlagen, gibt es eine Reihe von nützlichen Containerdienste nur Sie haben die Möglichkeit, zu verwenden , wenn Sie Ihre CDI Bean auch ein EJB durch Zugabe machen @Stateful
, @Stateless
oder @Singleton
auf sie.
Hier ist eine kurze Liste, wann ich die EJBs ausbreche.
Verwenden von JAX-WS
JAX-WS verfügbar machen @WebService
. Ich bin faul. Wenn das @WebService
auch ein EJB ist, müssen Sie es nicht auflisten und als Servlet in der web.xml
Datei zuordnen . Das ist Arbeit für mich. Außerdem habe ich die Möglichkeit, eine der anderen unten genannten Funktionen zu verwenden. Für mich ist das also ein Kinderspiel.
Verfügbar für @Stateless
und @Singleton
nur.
Verwenden von JAX-RS
Offenlegen einer JAX-RS-Ressource über @Path
. Ich bin immer noch faul. Wenn der RESTful-Dienst auch ein EJB ist, erhalten Sie erneut eine automatische Erkennung und müssen ihn nicht zu einer JAX-RS- Application
Unterklasse oder Ähnlichem hinzufügen . Außerdem kann ich genau die gleiche Bohne wie eine aussetzen, @WebService
wenn ich eine der unten genannten großartigen Funktionen nutzen möchte oder möchte.
Verfügbar für @Stateless
und @Singleton
nur.
Startlogik
Laden beim Start über @Startup
. Derzeit gibt es in CDI kein Äquivalent dazu. Irgendwie haben wir es versäumt, so etwas wie ein AfterStartup
Ereignis in den Container-Lebenszyklus einzufügen. Wenn wir das getan hätten, hätten Sie einfach eine @ApplicationScoped
Bohne haben können, die darauf gehört hat, und das wäre praktisch dasselbe wie eine @Singleton
mit @Startup
. Es ist auf der Liste für CDI 1.1.
Nur für verfügbar @Singleton
.
Parallel arbeiten
@Asynchronous
Methodenaufruf. Das Starten von Threads ist in jeder serverseitigen Umgebung ein No-No. Zu viele Threads zu haben, ist ein ernstzunehmender Leistungskiller. Mit dieser Anmerkung können Sie Dinge parallelisieren, die Sie mithilfe des Thread-Pools des Containers ausführen. Das ist fantastisch.
Zur Verfügung @Stateful
, @Stateless
und @Singleton
.
Arbeit planen
@Schedule
oder ScheduleExpression
ist im Grunde ein Cron oder eine Quartz
Funktionalität. Auch sehr genial. Die meisten Behälter verwenden dafür nur Quarz unter der Decke. Die meisten Leute wissen jedoch nicht, dass Planungsarbeiten in Java EE transaktional sind! Wenn Sie eine Datenbank aktualisieren und dann einige Arbeiten planen und eine davon fehlschlägt, werden beide automatisch bereinigt. Wenn der EntityManager
Aufruf zum Fortbestehen fehlschlägt oder ein Problem beim Löschen auftritt, müssen Sie die Planung der Arbeit nicht aufheben. Ja, Transaktionen.
Verfügbar für @Stateless
und @Singleton
nur.
Verwenden von EntityManagern in einer JTA-Transaktion
Der obige Hinweis zu Transaktionen erfordert natürlich die Verwendung eines JTA
verwalteten EntityManager
. Sie können sie mit einfachem "CDI" verwenden, aber ohne die von Containern verwalteten Transaktionen kann es wirklich eintönig werden, die UserTransaction
Commit / Rollback-Logik zu duplizieren .
Verfügbar für alle Java EE - Komponenten einschließlich CDI, JSF @ManagedBean
, @WebServlet
, @WebListener
, @WebFilter
usw. Die @TransactionAttribute
Anmerkung ist jedoch zur Verfügung @Stateful
, @Stateless
und @Singleton
nur.
JTA verwaltet halten EntityManager
Mit der EXTENDED
verwalteten Funktion EntityManager
können Sie EntityManager
zwischen JTA
Transaktionen offen bleiben und die zwischengespeicherten Daten nicht verlieren. Gutes Feature für die richtige Zeit und den richtigen Ort. Verantwortungsbewusst verwenden :)
Nur für verfügbar @Stateful
.
Einfache Synchronisation
Wenn Sie eine Synchronisierung benötigen, sind die @Lock(READ)
und @Lock(WRITE)
Anmerkungen ziemlich gut. Sie können damit gleichzeitig kostenlos gleichzeitig verwalten. Überspringen Sie alle ReentrantReadWriteLock-Leitungen. Im selben Bucket @AccessTimeout
können Sie angeben, wie lange ein Thread warten soll, um Zugriff auf die Bean-Instanz zu erhalten, bevor er aufgibt.
Nur für @Singleton
Bohnen verfügbar .