Unsere Datenschutzrichtlinie wird in Kürze aktualisiert. Bitte sehen Sie sich die Vorschau an.

Java EE 7 Grundkurs

Abhängigkeiten injizieren

Testen Sie unsere 2016 Kurse

10 Tage kostenlos!

Jetzt testen Alle Abonnements anzeigen
Der nächste Schritt nach dem Hinzufügen einer Beans-Datei zu einem Projekt besteht darin, Abhängigkeiten zu definieren und zu injizieren. Dieser Vorgang erfolgt durch die Verwendung einer entsprechenden Annotation.

Transkript

In diesem Video werden wir uns mit dem Injizieren von Abhängigkeiten befassen. Wir werden klären, was und wo man überhaupt injizieren kann und wir werden ebenfalls besprechen, wie man einzelne Klassen oder komplette Packages von der Injizierung ausschließen kann. Lassen Sie uns aber zunächst einmal besprechen, wo wir Abhängigkeiten injizieren können. Dies kann nämlich auf drei Ebenen geschehen: entweder auf Ebene von Feldern oder auf Ebene von Methoden oder alternativ auch auf Ebene von Konstruktoren. Werfen wir nun einen Blick darauf, wie dies jeweils umgesetzt werden kann. Wir sehen hier eine Webapplikation. Diese Webapplikation verfügt über ein Servlet. Dieses Servlet definiert eine private Member-Variable vom Typ "KontakteManager" und lässt sich die entsprechende Instanz per CDI injizieren. Dies ist die Injektion auf Ebene eines Feldes. Wenn das Servlet das jetzt nicht mehr auf Ebene des Feldes machen möchte, dann ist das völlig problemlos möglich. Es kann beispielsweise auch eine Injektion auf Ebene einer Methode vornehmen. Zu diesem Zweck kann eine beliebige Methode, gern auch eine private Methode, wie in diesem Fall, genutzt werden, die ihrerseits über einen entsprechenden Parameter vom Typ der zu injizierenden Komponente verfügt. Dabei muss lediglich sichergestellt sein, dass sämtliche Parameter, die eine entsprechende Methode hat, auch über CDI verwaltbar sind. Das bedeutet letztlich in der Praxis, das sich dies nur für "Setter" anbietet, da die meistens nur einen Parameter haben. Die dritte Möglichkeit der Injektion ist auf Ebene der Klasse "KontakteManager" bereits umgesetzt. Hier wird die Injection auf Ebene des Konstruktors umgesetzt. Auch hier verfügt der Konstruktor über einen Parameter vom Typ der zu injizierenden Ressource. Alle drei Möglichkeiten und Ansätze sind gültig und valide. Sie unterscheiden sich naturgemäß ein wenig in ihrem Szenario. Das zuweisen an eine private Eigenschaft ist sicherlich die leichteste Variante, hat allerdings den Nachteil, dass während der Zuweisung, keine zusätzlichen Operationen vorgenommen werden können. Ob wir jetzt eine Zuweisung in den Konstruktor oder in einen Setter machen, ist an vielen Stellen eine eher politische und geschmackstechnische Entscheidung, als wirklich einem praktischen Nutzen geschuldet. In beiden Fällen ist nämlich inhaltlich eine ähnliche Funktionalität umsetzbar. Sie entscheiden, welche Form der Injection Sie nutzen möchten. Wenn wir über Injection reden, ist es natürlich so, dass wir noch einmal ganz kurz besprechen müssen, wie injiziert werden kann. Wir verwenden zu diesem Zweck jeweils eine Inject-Annotation auf der gewünschten Ebene. Es ist letztlich nur ein Fall zu beachten, nämlich wenn der "Bean Discovery Mode", der in der "beans.xml"-Datei definiert ist, den Wert "annotated" hat. Dann muss sichergestellt sein, dass jede einzelne zu injizierende Bean mit einer CDI-Annotation versehen ist. Ist dies nicht der Fall, kann die Bean nicht gefunden werden und CDI wird Ihnen einen Fehler beim Start der Applikation [auswerfen], woraufhin die Applikation letztlich nicht verfügbar sein wird. Wenn Sie Abhängigkeiten injizieren, müssten Sie eigentlich nur eine sehr wichtige Regel beachten. Nämlich, dass die zu injizierende Bean eindeutig bestimmbar sein muss. Ist dies nicht der Fall, gibt es also mehrere Möglichkeiten, dann wird CDI nicht einfach zufälligerweise eine Variante auswählen, sondern eine Exception [auswerfen]; was wiederum dazu führt, dass Ihre Bean dafür sorgt, dass die gesamte Applikation nicht starten kann. Schauen wir uns einmal an, wie dies aussehen kann. Sie sehen hier die Klasse "KontakteProvider". Diese Klasse KontakteProvider wird in der Applikation genutzt, um dem KontakteManager Daten zuzuführen. Aus Testzwecken habe ich nun eine zweite Version dieser Klasse gebaut, nämlich den "TestKontakteProvider". Diese Implementierung soll nun ebenfalls aktiviert werden. Damit ich dies machen kann, muss ich oberhalb der Klasse eine CDI-Annotation hinzufügen. Ich entscheide mich hier für die Dependent-Annotation. Dies sorgt nun dafür, dass es zwei Möglichkeiten innerhalb meiner Applikation gibt, wie ein KontakteProvider aufgelöst werden kann. Nämlich einmal auf die originale Implementierung und einmal auf diese Klasse, die von der originalen Implementierung erbt. Wenn ich jetzt meine Applikation neu starte, werde ich einen entsprechenden Fehler in der Konsole angezeigt bekommen. Nämlich diesen Fehler, dass es letztlich mehrere Möglichkeiten der Injizierung für einen KontakteProvider geben kann. Nun ist guter Rat wahrscheinlich teurer, als man vielleicht denkt. Die einzige Möglichkeit, die einem spontan einfallen dürfte, ist, den TestKontakteProvider wieder zu entfernen. Das bedeutet letztendlich, die Annotation zu entfernen. Dies wird jedoch nur funktionieren, wenn der Bean Discovery Mode meiner Applikation nicht auf "All" steht. Steht der Wert auf "All", habe ich immer noch zwei mögliche Implementierungen zur Auswahl und das Problem ist nicht behoben. Lassen Sie uns aus diesem Grund einmal nachschauen, welche Optionen es noch gibt. Wenn ich Beans und Packages ausschließen möchte von der Dependency Injection, geschieht dies mit Hilfe von sogenannten Exclude-Filtern. Diese Exclude-Filter kann ich definieren in der Datei "beans.xml". Dort kann ich entweder über den Tree-View gehen und das Ganze grafisch machen oder im Quellcode einen entsprechenden Eintrag vornehmen. So ein Exclude-Filter verfügt letztlich über eine Name-Eigenschaft und diese Name-Eigenschaft zeigt auf den vollqualifizierten Klassennamen der Klasse, die auszuschließen ist. Ich kann zusätzlich Platzhalter verwenden, weil manchmal möchte ich beispielsweise mehrere Klassen aus einem Package ausschließen. Dann kann ich das machen, indem ich den Platzhalter Stern [*] benutze. Das ist hier dargestellt. In diesem Fall würden alle Klassen aus dem Package "com.acme.rest" von Dependency Injection ausgeschlossen werden. Es gibt noch einen zweiten Platzhalter, den ich benutzen kann, nämlich einen doppelten Stern [**]. Dieser bedeutet, schließe alle Klassen aus diesem Package und alle untergeordneten Packages von Dependency Injection aus. Darüber hinaus bin ich auch noch in der Lage, Bedingungen zu definieren. Die "if-class-not-available"-Bedingung definiert, dass der Filter nur dann zuschlägt, wenn tatsächlich die angegebene Klasse nicht im Klassenpfad vorhanden ist. Die "if-class-available"-Bedingung definiert, dass der Filter dann zuschlägt, wenn eine Klasse vorhanden ist und die "if-system-property"-Bedingung definiert, dass der Filter dann ausgewertet wird, wenn eine Systemeigenschaft vorhanden ist und/oder einen bestimmten Wert hat. Dies kann ich miteinander kombinieren. Werfen wir einen kurzen Blick darauf, wie ich dies machen kann. Wenn ich mir meine Datei "beans.xml" anschaue und einen Doppelklick ggf. drauf [ausführe], um den Editor zu öffnen, dann sehe ich bereits, es gibt ein Scan-Element in dieser Datei. Hier kann ich Exclude-Filter über den Button "Add" hinzufügen und beispielsweise den bereits vorhin erwähnten Filter, diesen Testfilter, von der Dependency Injection ausschließen. Wenn ich den Filter so hinzugefügt habe, kann ich einen Rechtsklick darauf machen und die bereits besprochenen Optionen und Bedingungen ebenfalls mit hinzufügen. Darauf verzichten wir in diesem Fall. Sobald ich diesen Filter aktiviert habe, kann ich meine Applikation neu deployen und werde keine Fehlermeldung mehr erhalten. Als Alternative zu den Filtern, die in der "beans.xml"-Datei hinterlegt sind, kann ich die Vetoed-Annotation benutzen. Diese lässt sich auf zwei Ebenen einsetzen. Entweder auf Ebene einer Klasse, dann sieht es so aus wie in diesem Beispiel; damit ist diese Klasse von der Dependency Injection ausgeschlossen. Oder ich kann sie einsetzen auf Ebene von Packages. Das wird definiert, indem ich das Package deklariere und da drüber die Vetoed-Annotation setze. Nun ist das komplette Package, einschließlich aller enthaltenen Klassen, von Dependency Injection ausgeschlossen. Wir haben in diesem Video gelernt, wie wir Dependency Injection auf Methoden- und Konstruktorebene sowie auf Member-Ebene anwenden können. Ebenfalls haben wir besprochen, was passieren kann, wenn es mehrere Möglichkeiten für das Erzeugen von Klassen gibt. Dann ist nämlich die Eindeutigkeit nicht mehr gegeben und es gibt einen Fehler. Aus diesem Grund haben wir uns über Exclude-Filter und die Vetoed-Annotation unterhalten.

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!