Am 14. September 2017 haben wir eine überarbeitete Fassung unserer Datenschutzrichtlinie veröffentlicht. Wenn Sie video2brain.com weiterhin nutzen, erklären Sie sich mit diesem überarbeiteten Dokument einverstanden. Bitte lesen Sie es deshalb sorgfältig durch.

Java EE 7 Grundkurs

Lebenszyklus-Methoden und Interzeptoren von EJB

LinkedIn Learning kostenlos und unverbindlich testen!

Jetzt testen Alle Abonnements anzeigen
Der Lebenszyklus von Enterprise Java Beans kann per Interzeptor oder Dekorator sowie mit Hilfe von Lebenszyklusannotationen auf Methodenebene begleitet werden.

Transkript

In diesem Video werden wir uns mit Lebenszyklus-Methoden und Interzeptoren beschäftigen. Lebenszyklus-Methoden und Interzeptoren sind Mechanismen, mit deren Hilfe wir auf der einen Seite auf bestimmte Ereignisse, die im Lebenszyklus einer EJB auftreten können, reagieren können und auf der anderen Seite die Ausführung von Methoden und Konstruktoren begleiten und um zusätzliche Funktionalitäten erweitern können. Jave EE verwendet zum Begleiten des Lebenszykluses Interzeptoren oder Methoden-Callbacks. Interzeptoren werden dabei für sogenannte Coss-Cutting-Concerns verwendet. Das heißt, für Dinge, die übergreifend von verschiedenen Arten von Komponenten genutzt werden. Beispielsweise Transaktionssteuerung, Logging oder Sicherheitsaspekte. Methoden-Callback, also Lebenszyklus-Methoden, werden genutzt, um die Lebenszyklen der Beans zu begleiten. Diese Lebenszyklus-Methoden sind ganz normale Methoden. Das bedeutet, wir müssen dort keinerlei spezielle Logik anwenden, um solche Methoden zu schreiben. Im Gegenteil, diese Methoden sind sogar oftmals als privat markiert und sie verfügen über keine Parameter. Stattdessen werden sie mit Annotationen versehen. Dabei gibt es vier verschiedene Annotationen, die wir einsetzen können. PostConstruct als Annotation besagt, dass eine damit annotierte Methode aufgerufen wird, sobald die EJB erzeugt wurden und mit den nötigen Referenzierungen versehen worden ist. Wir können diese Methoden nutzen, um nachdem wir ja nun alle benötigten Informationen zusammen haben, die Bean noch weiter zu initialisieren und für ihren eigentlichen produktiven Arbeitseinsatz vorzubereiten. Eine Methode, die mit der PreDestroy Annotation versehen ist, wird aufgerufen, wenn die Bean ihre Tätigkeit erledigt hat. Das heißt, bevor sie vom Application Container verworfen wird. Wir können dies nutzen, um noch einmal eventuell benötigte Ressourcen wieder freizugeben. Eine Methode, die mit PrePassivate annotiert worden ist, die gibt es übrigens nur auf Ebene des Stateful Session Beans, wird aufgerufen bevor der Zustand der Beans gespeichert wird und die Bean danach passiviert wird. Das heißt, hier können wir noch einmal den Zustand manipulieren und eventuell weiterführende Aufgaben anstoßen. Wenn eine Stateful Session Bean aus der Passivation zurück kommt, das heißt, wieder aktiviert wird, dann wird der Zustand geladen. Anschließend wird eine Methode, die mit der PostActivate Annotation versehen ist, aufgerufen. Hier können wir den Zustand überprüfen und andere weiterführende Initialisierungstätigkeiten vornehmen. Solche Lebenszyklus-Methoden dürfen RuntimeExceptions werfen. Das bedeutet, andere Exceptions sind nicht erlaubt. Wir sind also nicht in der Lage, Methoden zu definieren, bei denen wir das Pros Schlüsselwort benutzen und dann eben eine eigene spezialisierte Exception werfen. Interzeptoren sind eine andere Technologie. Diese Interzeptoren, die im EJB-Umfeld eingesetzt werden, werden wie CDI-Interzeptoren deklariert. Eigentlich sind es streng genommen CDI-Interzeptoren. Das bedeutet, wir haben drei Schritte, die wir gehen müssen, bevor so ein Interzeptor einsatzfähig ist. Zum einen müssen wir eine Platzhalter-Annotation versehen mithilfe eines Interceptor-Bindings. Dann muss der Interzeptor selber geschrieben werden. Das ist eine ganz normale Java Klasse, die mit der Interceptor-Annotation versehen ist und der zuvor geschriebenen Platzhalter-Annotation und danach wird diese Platzhalter-Annotation auf Ebene von Methoden oder Klassen notiert und überall dort, wo dies geschehen ist, wird dann der Interzeptor, so er aktiv ist, eingebunden. Dabei ist zu beachten, dass zu einem Interzeptor-Binding, also zu einer Platzhalter-Annotation es durchaus mehrere Interzeptoren geben kann. Deswegen sind wir auch in der Lage, die Reihenfolge der Interzeptoren indirekt zu steuern und zwar über deren Priority-Annotation. So ein Interzeptor-Binding wird in einer eigenen Annotation definiert. Das ist selber eine benannte Annotation. In diesem Fall MyAroundInterceptor und diese Annotation ihrerseits ist wieder annotiert mit der Interceptor-Binding Annotation. Eine so definierte Platzhalter-Annotation für einen Interceptor wird dann auf Ebene des Interceptors selber ebenfalls noch einmal deklariert. Der Interceptor, an und für sich, ist eine ganz normale Java Klasse. Diese ist mit der Platzhalter-Annotation und mit der Annotation Interceptor versehen. Damit der Interceptor eingebunden werden kann, wenn ein Konstruktor durchlaufen wird, verwenden wir auf der entsprechenden Methode, die aufgerufen werden soll, die AroundConstruct Annotation. Wenn der Interceptor eingebunden werden soll, wenn eine Methode aufrufen wird, verwenden wir die AroundInvoke Annotation auf Ebene der Methode, die eingebunden werden soll. So ein fertig definierter Interceptor muss nun noch im letzten Schritt auf Klasse-, Methoden- oder Konstruktorebene aktiviert werden. Dies geschieht, indem die Platzhalter-Annotation an einer geeigneten Stelle notiert wird. In diesem Fall oberhalb einer Stateful Session Bean. Und das würde bedeuten, dass alle Interzeptoren, die auf diese MyAroundInterceptor Platzhalter-Annotation reagieren, eingebunden werden, sobald eine Methode oder der Konstruktor dieser Bean durchlaufen wird. Alternativ kann ich diese Aktivierung auch auf Ebene der ejb-jar.xml Datei vornehmen. Das geht allerdings wirklich nur für Java EE Applikationen. Ist also im Web-Umfeld nicht einsetzbar. Sehen wir uns nun an, wie wir die besprochenen Lebenszyklus-Annotationen einsetzen können und sehen wir uns auch an, wie wir einen Interzeptor tatsächlich definieren und zum Laufen bringen können. Ich habe alle vier möglichen Lebenszyklus-Annotationen bereits einmal implementiert. Hier auf Ebene einer Stateful Session Bean. Über die Funktionalität wollen wir besser kein Wort verlieren. Einzige Aufgabe dieser Methoden ist, zu demonstrieren, wie wir diese Annotationen einsetzen können. Die PostConstruct Annotation genauso wie die PreDestroy, PrePassivate und PostActivate Annotationen befinden sich stets auf Ebene von Methoden. Diese Methoden können gerne privat sein, müssen das natürlich nicht sein und diese Methoden nehmen allesamt keine Parameter entgegen. Die Einbindung der Methoden obliegt dem System. Das heißt, nur weil ich diese Annotation gesetzt habe, kann ich nicht erwarten, dass wenn ich die Applikation ausführe, ich sofort alle vier Methoden in Aktion sehe, aber ich kann erkennen, dass wenn zumindest eine neue Instanz der Stateful Session Bean initialisiert worden ist, die mit PostConstruct annotierte Methode aufgerufen wird. Die anderen Methoden werden wir im Moment nicht in Aktion sehen können, denn deren Einbindung und speziell auch die Frage, wann zum Beispiel passiviert wird und wann aktiviert wird, wann eine Session beendet ist, das obliegt jeweils dem Application Server. Eine weitere Verwendung der PostConstruct Annotation habe ich hier in einer anderen Klasse. Das ist eine Singleton Session Bean, die mit der Startup Annotation versehen wird, also direkt mit der Applikation bereits gestartet worden ist. Wenn ich die Applikation nun noch einmal neu starte und wir die Ausgabe verfolgen, werden wir sehr zeitig, noch bevor eventuelle Stateful oder Stateless Session Beans zuschlagen können, bereits die Ausgabe, initialisiere Daten sehen. Ich starte jetzt gerade die Applikation noch einmal neu und wir werden die Konsole beobachten. Und Sie sehen hier die Ausgabe, initialisiere Daten. Genau diese Ausgabe, die von dieser PostConstruct Methode erzeugt wird. Sie sehen, diese Methoden werden schon zuverlässig aufgerufen. Nur, wie gesagt, es ist für Sie nicht unbedingt ersichtlich, wann genau das der Fall sein wird. Ich habe in diesem Projekt ebenfalls einen Interceptor implementiert. Dieser Interceptor wird angesprochen über den Platzhalter Logging, also diese Annotation, die wir hier definieren, ist der Platzhalter für einen oder mehrere tatsächlich verwendeten Interzeptoren. Diese Annotation selbst ist versehen mit der Interceptor-Binding Annotation und damit ist klar, dass es eben eine Annotation ist, die für einen Interzeptor stehen wird. Der Interzeptor ist ein AroundConstruct Interceptor. Das bedeutet, wir haben hier eine Funktionalität implementiert, die mit AroundConstruct annotiert ist. Der Interzeptor, bevor wir uns weiter der eigentlichen Funktionalität widmen, ist mit der Annotation Interceptor versehen. Er verfügt über eine Priority. Damit ist der aktiv und er ist als dependent gekennzeichnet. Dies ist nötig, weil dieser Interceptor eigentlich streng genommen ein CDI-Interceptor ist, der eben nur auf EJB Komponenten angewendet werden kann. Und damit CDI-Interzeptoren von der CDI gefunden werden können, müssen sie über eine CDI Annotation verfügen, eben beispielsweise dependent. Die AroundConstruct Annotation besagt, dass diese Methode, die damit annotiert worden ist, um einen Konstruktor herum aufgerufen wird. Das heißt, sie wird eingebunden bevor der Konstruktor einer Klasse aufgerufen wird. Die Aufgabe dieser Methode besteht dann darin, das zu tun was sie tun muss und sie muss über die Methode proceed des übergebenden Invocation Contextes den eigentlichen Konstruktor einbinden. Wenn sie dies nicht tut, dann wird das Erzeugen der Klasse möglicherweise fehlschlagen. Analog können wir eine AroundInvoke Methode implementieren. Diese würde eben aufgerufen werden, wenn eine Methode aufgerufen wird. Nachdem der Interzeptor so definiert ist und mit der Logging Annotation versehen worden ist, können wir diese Logging Annotation nun an geeigneten Stellen einsetzen. Ich habe dies einmal auf Ebene der Singleton Session gemacht, die beim Start des Servers aufgerufen wird. Auch hier gibt es jetzt diese Logging Annotation. Das bedeutet, dass der Konstruktor dieser Singleton Session Bean nunmehr nicht mehr direkt aufgerufen wird, sondern stets über den Interceptor. Analoges habe ich bei der Stateful Session Bean gemacht. Auch hier gibt es nun die Logging Annotation auf Ebene dieser Stateful Session Bean. Und wann immer nun entweder die Singleton Session Bean oder die Stateful Session Bean erzeugt wird, werden wir eine entsprechende Meldung in der Ausgabe finden. Lassen Sie uns die Applikation einmal durchstarten und dann werden wir die Ausgabe beobachten. Sie sehen hier die Ausgabe unseres Interceptors, nämlich before construct und after construct. Und wir sehen welche Klasse tatsächlich eingebunden wird, nämlich ein Platzhalter für die eigentliche Singleton Session Bean. Wenn ich jetzt dafür sorge, dass die Stateful Seassion Bean aufgerufen wird, werden wir analoge Ausgaben sehen. Auch hier können wir nun feststellen, dass der Interceptor tätig geworden ist bevor und nachdem der Konstruktor der Klasse eingebunden worden ist. Wir haben in diesem Video uns über Lebenszyklus-Callbacks und über Interzeptoren unterhalten und haben gesehen, wie wir diese im EJB-Umfeld einsetzen können. Die Lebenszyklus-Callbacks, also Methoden, die eingebunden werden, wenn bestimmte Lebenszyklen eintreten, werden von der EJB-Runtime eingebunden. Sie können sie lediglich deklarieren. Sicher ist nur, wann eine mit PostConstruct annotierte Methode aufgerufen wird. Bei allen anderen Annotationen, also PreDestroy, PostActivate und PrePassivate ist Ihnen nicht garantiert, wann die entsprechenden Methoden tatsächlich eingebunden werden, denn dies hängt von den EJB-Runtime ab, denn die muss sich ja entscheiden, dass sie die Daten speichert und wiederherstellt oder aber eine Session beendet. Wir haben ebenfalls über Interzeptoren gesprochen und haben und angeschaut, wie wir einen Interzeptoren bauen können, der beim Erzeugen von neuen Klasseninstanzen tätig wird. Sie sehen, es gibt auch im Lebenszyklus-Umfeld, einem eigentlich nicht so schönen Thema, doch eine ganze Menge Dinge zu lernen und zu beachten.

Java EE 7 Grundkurs

Lernen Sie die Grundlagen der Programmierung mit Java EE 7 verstehen und anwenden.

6 Std. 4 min (44 Videos)
Derzeit sind keine Feedbacks vorhanden...
 

Dieser Online-Kurs ist als Download und als Streaming-Video verfügbar. Die gute Nachricht: Sie müssen sich nicht entscheiden - sobald Sie das Training erwerben, erhalten Sie Zugang zu beiden Optionen!

Der Download ermöglicht Ihnen die Offline-Nutzung des Trainings und bietet die Vorteile einer benutzerfreundlichen Abspielumgebung. Wenn Sie an verschiedenen Computern arbeiten, oder nicht den ganzen Kurs auf einmal herunterladen möchten, loggen Sie sich auf dieser Seite ein, um alle Videos des Trainings als Streaming-Video anzusehen.

Wir hoffen, dass Sie viel Freude und Erfolg mit diesem Video-Training haben werden. Falls Sie irgendwelche Fragen haben, zögern Sie nicht uns zu kontaktieren!