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

Singleton Beans

LinkedIn Learning kostenlos und unverbindlich testen!

Jetzt testen Alle Abonnements anzeigen
Die EJB-Lite-Spezifikation verfügt mit den Singleton Beans über eine Spezialform der Stateful Session Beans. Diese existieren exakt einmal im Kontext einer Application-Server-Instanz.

Transkript

Setzen Sie gerne statische Konstrukte ein, also Variablen, die es nur einmal pro Applikation gibt? Dann sollten Sie sich Singleton Session Beans näher anschauen, denn diese setzen diesen Ansatz auf Ebene der Java EE um. Und in diesem Video werden wir uns mit Singleton Session Beans auseinandersetzen. Und wir werden klären, wie wir sie einsetzen können, wie wir sie initialisieren können und wie wir mit parallelem Zugriff auf diese einmaligen Objekte umgehen können. Singleton Session Beans werden einmal pro Applikation erzeugt. Das ist ein Unterschied zu statischen Variablen. Die werden nämlich einmal pro Applikation pro Server erzeugt. Da eine Java-EE-Applikation allerdings auf mehreren Clustern, also Servern, gleichzeitig laufen kann und die Zustände dann repliziert werden zwischen den verschiedenen Cluster-Membern, wäre dies ein gewaltiges Problem, denn statische Dinge werden nicht repliziert. Und so hätten Sie ganz schnell einen Zustand, auf dem bei jedem Server in einer statischen Variablen ein anderer Wert stünde. Diesem Problem begegnen die Singleton Session Beans, denn die werden wirklich einmal pro kompletter Applikation erzeugt und dann über die verschiedenen Cluster-Member hinweg repliziert. Eine Singleton Session Bean ist eine normale Java-Klasse, ein POJO, ein Plain Old Java Object. Auf Ebene der Klasse selbst ist die Singleton-Annotation hinterlegt. So eine Singleton Session Bean hat einen Status. Der wird über ein Cluster repliziert. Dadurch ist eine Singleton Session Bean sicherlich nicht so effizient wie eine Stateless Session Bean. Eine Singleton Session Bean unterstützt, wie jede andere Session Bean auch, grundsätzlich parallele Zugriffe. Aber während bei den anderen Session Beans diese parallelen Zugriffe keinerlei Auswirkungen haben, weil entweder auf unterschiedlichen Status gearbeitet wird, oder weil die Beans eh keinen Status haben, kann das bei der Singleton Session Bean schon gewaltige Auswirkungen haben, denn die haben ja einen Status, existieren aber genau einmal. Eine Singleton Session Bean kann per Remote View oder per Local View oder per No Interface View deklariert werden. "No Interface View" bedeutet: Diese Singleton Session Bean verfügt nicht über ein Home oder ein Remote Interface. So ein Remote Interface ist nichts anderes als ein normales Interface, das letztlich weniger Funktionalitäten zeigt als die Bean insgesamt zur Verfügung stellt, und mit der Remote-Annotation versehen ist. Eine Bean, die mit einem Remote View, also einem Remote Interface, versehen ist, kann dann von Komponenten genutzt werden, die nicht in derselben Java-EE-Applikation liegen. Local View ist ein Interface, das mit der Local-Annotation versehen ist und das Beans, die in demselben Java-EE-Application-Server deployed sind, zusätzliche Möglichkeiten auf der Bean selber einräumt. Und wenn sie keines dieser Interfaces haben, dann spricht man von einem No Interface View. So eine Singleton Session Bean mit No Interface View kann nicht außerhalb der Applikation genutzt werden. Bei Singleton Session Beans ist der Container verantwortlich für die Initialisierung. Dabei wird die Bean normalerweise bei der ersten Verwendung initialisiert. Es gibt aber auch die Möglichkeit, mit Hilfe der Startup-Annotation anzugeben, dass die Bean beim ersten Start der Applikation bereits initialisiert wird. Das heißt, es passiert deutlich, bevor der erste Zugriff von irgendwelchen Benutzern überhaupt eintritt. Sie geben diese Startup-Annotation auf der Klassenebene an, vor oder nach der Singleton-Annotation. Das spielt keine Rolle. Wenn Sie mehrere Singleton Session Beans haben, dann ist die Reihenfolge der Initialisierung vom Container bestimmt. Sie haben normalerweise keine direkte Möglichkeit, da einzugreifen. Aber es gibt die DependsOn-Annotation. Und mit deren Hilfe können Sie eine Sequenz definieren. Das heißt, Sie können sagen, dass eine Singleton Session Bean von einer anderen Singleton Session Bean abhängig ist. Das kann so aussehen wie in diesem Beispiel. Hier wird die Singleton Session Bean "Bar" deklariert, und sie verfügt über die DependsOn-Annotation. Und die DependsOn-Annotation sagt aus, dass diese Singleton Session Bean von der Session Bean "Foo" abhängig ist. In diesem Fall würde also zunächst die Singleton Session Bean "Foo" initialisiert werden und erst danach die Singleton Session Bean "Bar". So eine Singleton Session Bean hat einen relativ einfachen Lebenszyklus. Sie wird erzeugt, wenn die Applikation gestartet wird. Danach ist sie aktiv. Ihr Status wird über die verschiedenen Cluster-Member, so es solche gibt, repliziert. Und irgendwann, wenn die ganze Applikation aus dem Server entladen wird, dann wird auch die Bean wieder verworfen. Das kann aber deutlich später sein als die Erzeugung. So einen Lebenszyklus können Sie durch Annotationen begleiten. Es gibt zwei Annotationen, die uns an der Stelle interessieren könnten. Eine Methode, die mit der PostConstruct-Annotation versehen wird, wird nämlich aufgerufen, nachdem die Instanz erzeugt und alle Injizierungen vorgenommen worden sind. Das heißt, die Bean ist jetzt im Grunde arbeitsfähig, aber wir haben noch eine Möglichkeit, dazwischen zu gehen und die Bean selber noch einmal von Hand nachzuinitialisieren. Eine Methode, die mit der Annotation "PreDestroy" versehen ist, wird aufgerufen, bevor die Instanz verworfen wird. Sehr wichtig bei Singleton Session Beans ist es, sich Gedanken über die Parallelität zu machen. Da es ja nur eine Instanz gibt, kann es durchaus sein, dass der Status von verschiedenen Prozessen parallel manipuliert werden soll. Generell ist es so, dass der Container parallele Zugriffe regelt. Wir können das allerdings auf Klassenebene festlegen. Dabei legt der Container normalerweise die Reihenfolge fest. Dies ist die Standardeinstellung. Das Ganze können wir auch explizit ausdrücken, indem wir die ConcurrencyManagement- Annotation verwenden und dort den Wert "Container" hineingeben. Wenn wir das selber regeln wollen, dann geben wir auf Klassenebene die ConcurrencyManagement-Annotation mit dem Wert "Bean" an. Nun ist die Bean selber verantwortlich für parallelen Zugriff, das heißt sie muss sich selber über Locking und Unlocking Gedanken machen. Auch wenn der Container die Zugriffe regelt, haben wir immer noch Eingriffsmöglichkeiten. Alle Methoden haben nämlich implizit den sogenannten LockType-Wert "WRITE". Es gibt zwei LockType-Typen, nämlich "WRITE" und "READ". LockType-Typ "WRITE" bedeutet, dass es einen sequenziellen Zugriff gibt. Das bedeutet, dass Clients warten müssen, bis der Client, der gerade in der Methode drin ist, diese Methode wieder verlassen hat. Der LockType-Typ "READ" sagt: Es gibt parallelen Zugriff. Das kann natürlich dann, wenn der Status manipuliert wird, zu Problemen führen. Auf der anderen Seite ist der LockType "READ" deutlich schneller als der LockType "WRITE". Dieses Verhalten können wir mit Hilfe der Lock-Annotation auf Klassen- und/oder Methodenebene ändern. Wenn wir den LockType-Typ ändern wollen, dann kann das auf Methodenebene geschehen. In diesem Fall gilt die Standardeinstellung des Containers, denn ConcurrencyManagement hat den Wert "CONTAINER". Der Standardwert ist "WRITE". Die Methode "getState" ist jetzt allerdings mit dem LockType-Typ "READ" ausgestattet, das heißt dort können mehrere Instanzen parallel drauf arbeiten. Die Methode "setState" ist noch einmal explizit mit dem LockType-Wert "WRITE" versehen worden. Das ist eigentlich gar nicht nötig. Wenn der LockType auf der Klassenebene festgelegt ist, dann gilt er für alle Klassen. Das bedeutet, die Methode "getStatus" hat automatisch den LockType "READ", das heißt sie kann parallel genutzt werden. Nun können wir auf Ebene der einzelnen Methoden ein abweichendes Verhalten deklarieren. In dem Fall wäre die Methode "setStatus" mit dem LockType-Typ "WRITE" versehen. Das bedeutet, wenn hier Komponenten arbeiten wollen, dann müssen sie warten, bis eine Komponente, die eventuell gerade in dieser Methode ist, diese Methode verlassen hat. Methoden, die mit diesem LockType-Typ "WRITE" versehen sind, können dadurch letztlich, wenn sie stehen bleiben in so einer Methode, theoretisch die komplette Ausführung blockieren. Aus diesem Grund gibt es die Möglichkeit, sogenannte AccessTimeouts zu deklarieren. Das ist eine Annotation. Und da geben wir den Wert in Millisekunden an. Wir können auch andere Werte angeben, also beispielsweise Sekunden oder Minuten. Das lässt sich auf Ebene dieser Annotation aussteuern. Wenn dann so ein Timeout auftritt, wird eine Exception geworfen. Die kann abgefangen werden. Die kann aber auch erst einmal durcheskaliert lassen werden, damit Benutzer informiert werden beziehungsweise, damit geeignete Maßnahmen ergriffen werden können. Um so ein Timeout festzulegen, können wir die AccessTimeout-Annotation auf Klassenebene setzen. Dann gilt sie wieder für alle Methoden. Oder wir setzen einen abweichenden Wert auf Ebene von besonders potenziell lang laufenden Methoden, die aber dann dennoch irgendwann eingeschränkt werden sollen. Hier in dem Fall wäre das die untere Methode. Und die hätte ein AccessTimeout von 360.000 Millisekunden, also 360 Sekunden. Und das wären sechs Minuten. Nachdem wir soviel theoretisch jetzt über die Singleton Session Beans gehört haben, lassen Sie uns doch einfach einmal sehen, wie wir eine Singleton Session Bean deklarieren können, und wie wir sie sinnvoll einsetzen können. Aufgrund ihres Hintergrundes eignen sich Singleton Session Beans wunderbar dazu, komplette Applikationen zu initialisieren. Wir können dies hier nachstellen, indem wir diese hier in einer normalen Stateless Session Bean vorhandene Methode "initialize" einmal in eine Singleton Session Bean auslagern. Zu diesem Zweck legen wir eine neue Singleton Session Bean an. Ich mache einen Rechtsklick auf das entsprechende Package und wähle dann aus dem Kontextmenü den Eintrag "New" und dann "Class". Die Klasse können wir jetzt nennen wie wir wollen. Ich nenne sie "Initializer". Da eine Singleton Session Bean eine ganz normale POJO ist, reicht es aus, wenn ich sie jetzt annotiere. Dafür verwende ich die Singleton-Annotation. Ebenfalls gebe ich hier an, dass diese Bean beim Start des Application Servers eingebunden werden soll. So eine Singleton Session Bean benötigt keine öffentlichen Methoden. Das heißt, für uns ist es jetzt sehr einfach, die Initialisierung vorzunehmen. Zunächst jedoch müssen wir uns hier einen EntityManager injizieren lassen. Nun können wir eine Methode schreiben, die diese Bean initlialisiert. Wir annotieren diese Methode mit "PostConstruct". Dadurch ist sichergestellt, dass der EntityManager, den wir intern benötigen, schon vorinitialisiert ist und der Bean zugewiesen ist. Das bedeutet, dass alle benötigten Referenzierungen bereits existieren. Jetzt werde ich den relevanten Code aus der anderen Bean herüberkopieren. Damit das Ganze vernünftig funktioniert, lasse ich mir jetzt auch die andere Bean injizieren. Das mache ich mit Hilfe der EJB-Annotation. Und nun kann ich mit dieser Bean arbeiten und die entsprechenden Funktionalitäten aufrufen und kann die Logik aus dieser BookManager-Bean entfernen. Funktional verhält sich die Applikation nun genauso wie vorher. Aber es gibt dann doch einen gewaltigen Unterschied. Diese initialize-Methode und der Inhalt werden direkt beim Start der Applikation ausgeführt und nicht erst, wenn der erste Client sich mit dem BookManager connectet. Damit ist sichergestellt, dass Clients immer schon mit einem konkreten und definierten Zustand konfrontiert sind und nicht erst warten müssen, bis bestimmte Vorbereitungsarbeiten abgeschlossen sind. Damit ist diese Singleton Session Bean fertig und wir können sie auf der Applikation deployen. Wie Sie vielleicht eben kurz gesehen haben gab es einen Fehler beim Starten der Applikation. Dieser Fehler ist darauf zurückzuführen, dass ich hier eine EJB-Annotation mit einer normalen EJB-Instanz benutzen möchte. Daran ist nichts falsch, nur: Wenn wir uns diesen BookManager anschauen, der implementiert ein Interface "BookHandler". Und dieses Interface "BookHandler" stellt ein Remote View zur Verfügung. Nun ist dieser BookManager nicht mehr direkt nutzbar. Das Einzige, was wir nun machen müssen, damit wir die BookManager-Klasse selbst in eine andere Bean injizieren lassen können, ist, mit der LocalBean- Annotation zu arbeiten. Damit wird nämlich ausgesagt: Es gibt zwar ein Remote Interface für diese Bean, aber wir stellen auch die komplette Bean noch einmal lokal zur Verfügung. Und das Lokale ist genau das, was der Initializer hier benötigt. Wenn wir nun die Applikation deployen, werden wir feststellen, dass das Ganze funktioniert, dass es keine weiteren Fehlermeldungen gibt. Damit ist die Initialisierung der Applikation ausgelagert worden aus dieser BookManager-Klasse in eine eigene, spezialisierte Singleton Session Bean. Diese Session Bean ist mit der Startup-Annotation versehen worden. Und Sie haben auf diese Art und Weise die verschiedenen Aufgaben voneinander getrennt. Auch das ist ein sehr sinnvoller Aspekt bei der Arbeit mit Singleton Session Beans. In diesem Video haben wir Singleton Session Beans besprochen. Wir haben geklärt, was Singleton Session Beans sind und wo ihre Einsatzszenarien sind. Wir haben ebenfalls aufgezeigt, wie wir dafür sorgen können, dass solche Singleton Session Beans direkt beim Start der Applikation ausgeführt werden. Singleton Session Beans sind ein sehr mächtiger Mechanismus, den Sie gezielt einsetzen können und sollten.

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!