JavaRush /Java-Blog /Random-DE /Ein kurzer Ausflug in die Abhängigkeitsinjektion oder „Wa...
Viacheslav
Level 3

Ein kurzer Ausflug in die Abhängigkeitsinjektion oder „Was ist CDI noch?“

Veröffentlicht in der Gruppe Random-DE
Die Grundlage, auf der die beliebtesten Frameworks heute aufbauen, ist die Abhängigkeitsinjektion. Ich schlage vor, einen Blick darauf zu werfen, was die CDI-Spezifikation dazu sagt, welche grundlegenden Fähigkeiten wir haben und wie wir sie nutzen können.
Ein kurzer Ausflug in die Abhängigkeitsinjektion oder

Einführung

Diese kurze Rezension möchte ich einer Sache wie CDI widmen. Was ist das? CDI steht für Contexts and Dependency Injection. Dies ist eine Java EE-Spezifikation, die Dependency Injection und Kontexte beschreibt. Weitere Informationen finden Sie auf der Website http://cdi-spec.org . Da CDI eine Spezifikation ist (eine Beschreibung, wie es funktionieren soll, eine Reihe von Schnittstellen), benötigen wir auch eine Implementierung, um es zu verwenden. Eine dieser Implementierungen ist Weld – http://weld.cdi-spec.org/ Um Abhängigkeiten zu verwalten und ein Projekt zu erstellen, verwenden wir Maven – https://maven.apache.org . Also haben wir Maven installiert, jetzt tun wir es Ich werde es in der Praxis verstehen, um das Abstrakte nicht zu verstehen. Dazu erstellen wir ein Projekt mit Maven. Öffnen wir die Befehlszeile (unter Windows können Sie mit Win+R das Fenster „Ausführen“ öffnen und cmd ausführen) und bitten Sie Maven, alles für uns zu erledigen. Zu diesem Zweck verfügt Maven über ein Konzept namens Archetyp: Maven Archetype .
Ein kurzer Ausflug in die Abhängigkeitsinjektion oder
Danach drücken Sie bei den Fragen „ Wählen Sie eine Zahl oder wenden Sie einen Filter “ und „ Wählen Sie die Version von org.apache.maven.archetypes:maven-archetype-quickstart “ einfach die Eingabetaste aus. Als nächstes geben Sie die Projektkennungen ein, den sogenannten GAV (siehe Naming Convention Guide ).
Ein kurzer Ausflug in die Abhängigkeitsinjektion oder
Nach erfolgreicher Erstellung des Projekts sehen wir die Aufschrift „BUILD SUCCESS“. Jetzt können wir unser Projekt in unserer Lieblings-IDE öffnen.

CDI zu einem Projekt hinzufügen

In der Einleitung haben wir gesehen, dass CDI eine interessante Website hat – http://www.cdi-spec.org/ . Es gibt einen Download-Bereich, der eine Tabelle mit den von uns benötigten Daten enthält:
Ein kurzer Ausflug in die Abhängigkeitsinjektion oder
Hier können wir sehen, wie Maven die Tatsache beschreibt, dass wir die CDI-API im Projekt verwenden. API ist eine Anwendungsprogrammierschnittstelle, also eine Programmierschnittstelle. Wir arbeiten mit der Schnittstelle, ohne uns Gedanken darüber zu machen, was und wie es hinter dieser Schnittstelle funktioniert. Die API ist ein JAR-Archiv, das wir in unserem Projekt verwenden werden, das heißt, unser Projekt beginnt, von diesem JAR abhängig zu sein. Daher ist die CDI-API für unser Projekt eine Abhängigkeit. In Maven wird ein Projekt in POM.xml-Dateien beschrieben ( POM – Project Object Model ). Abhängigkeiten werden im Abhängigkeitsblock beschrieben, zu dem wir einen neuen Eintrag hinzufügen müssen:
<dependency>
	<groupId>javax.enterprise</groupId>
	<artifactId>cdi-api</artifactId>
	<version>2.0</version>
</dependency>
Wie Sie vielleicht bemerkt haben, geben wir mit dem angegebenen Wert keinen Umfang an. Warum gibt es so einen Unterschied? Dieser Umfang bedeutet, dass uns jemand die Abhängigkeit zur Verfügung stellt. Wenn eine Anwendung auf einem Java EE-Server ausgeführt wird, bedeutet dies, dass der Server der Anwendung alle erforderlichen JEE-Technologien zur Verfügung stellt. Der Einfachheit halber arbeiten wir in dieser Rezension in einer Java SE-Umgebung, daher wird uns niemand diese Abhängigkeit zur Verfügung stellen. Weitere Informationen zum Abhängigkeitsbereich finden Sie hier: „ Abhängigkeitsbereich “. Okay, wir haben jetzt die Möglichkeit, mit Schnittstellen zu arbeiten. Aber wir brauchen auch die Umsetzung. Wie wir uns erinnern, werden wir Weld verwenden. Interessant ist, dass überall unterschiedliche Abhängigkeiten gegeben sind. Aber wir werden der Dokumentation folgen. Lesen wir daher „ 18.4.5. Festlegen des Klassenpfads “ und befolgen Sie die Anweisungen:
<dependency>
	<groupId>org.jboss.weld.se</groupId>
	<artifactId>weld-se-core</artifactId>
	<version>3.0.5.Final</version>
</dependency>
Es ist wichtig, dass die Third-Line-Versionen von Weld CDI 2.0 unterstützen. Daher können wir auf die API dieser Version zählen. Jetzt sind wir bereit, Code zu schreiben.
Ein kurzer Ausflug in die Abhängigkeitsinjektion oder

Initialisieren eines CDI-Containers

CDI ist ein Mechanismus. Jemand muss diesen Mechanismus kontrollieren. Wie wir oben bereits gelesen haben, handelt es sich bei einem solchen Manager um einen Container. Daher müssen wir es erstellen; es selbst wird nicht in der SE-Umgebung angezeigt. Fügen wir unserer Hauptmethode Folgendes hinzu:
public static void main(String[] args) {
	SeContainerInitializer initializer = SeContainerInitializer.newInstance();
	initializer.addPackages(App.class.getPackage());
	SeContainer container = initializer.initialize();
}
Wir haben den CDI-Container manuell erstellt, weil... Wir arbeiten in einer SE-Umgebung. In typischen Kampfprojekten läuft der Code auf einem Server, der dem Code verschiedene Technologien zur Verfügung stellt. Wenn der Server CDI bereitstellt, bedeutet dies dementsprechend, dass der Server bereits über einen CDI-Container verfügt und wir nichts hinzufügen müssen. Für dieses Tutorial verwenden wir jedoch die SE-Umgebung. Darüber hinaus ist der Behälter hier übersichtlich und verständlich dargestellt. Warum brauchen wir einen Container? Der Behälter darin enthält Bohnen (CDI-Bohnen).
Ein kurzer Ausflug in die Abhängigkeitsinjektion oder

CDI-Bohnen

Also, Bohnen. Was ist ein CDI-Behälter? Dies ist eine Java-Klasse, die einigen Regeln folgt. Diese Regeln werden in der Spezifikation im Kapitel „ 2.2. Welche Arten von Klassen sind Beans? “ beschrieben. Fügen wir eine CDI-Bean zum gleichen Paket wie die App-Klasse hinzu:
public class Logger {
    public void print(String message) {
        System.out.println(message);
    }
}
mainJetzt können wir diese Bean von unserer Methode aus aufrufen :
Logger logger = container.select(Logger.class).get();
logger.print("Hello, World!");
Wie Sie sehen, haben wir die Bean nicht mit dem neuen Schlüsselwort erstellt. Wir haben den CDI-Container gefragt: „CDI-Container. Ich brauche wirklich eine Instanz der Logger-Klasse, geben Sie sie mir bitte.“ Diese Methode heißt „ Dependency Lookup “, also die Suche nach Abhängigkeiten. Jetzt erstellen wir eine neue Klasse:
public class DateSource {
    public String getDate() {
        return new Date().toString();
    }
}
Eine primitive Klasse, die eine Textdarstellung eines Datums zurückgibt. Fügen wir nun die Datumsausgabe zur Nachricht hinzu:
public class Logger {
    @Inject
    private DateSource dateSource;

    public void print(String message) {
        System.out.println(dateSource.getDate() + " : " + message);
    }
}
Es ist eine interessante @Inject-Anmerkung erschienen. Wie im Kapitel „ 4.1. Einspritzpunkte “ der CDI-Schweißdokumentation angegeben, definieren wir mit dieser Anmerkung den Einspritzpunkt. Im Russischen kann man dies als „Implementierungspunkte“ lesen. Sie werden vom CDI-Container verwendet, um beim Instanziieren von Beans Abhängigkeiten einzufügen. Wie Sie sehen, weisen wir dem Feld dateSource keine Werte zu. Der Grund dafür ist die Tatsache, dass der CDI-Container innerhalb von CDI-Beans (nur solchen Beans, die er selbst instanziiert hat, d. h. die er verwaltet) die Verwendung von „ Dependency Injection “ zulässt. Dies ist eine weitere Art der Umkehrung der Kontrolle , ein Ansatz, bei dem die Abhängigkeit von jemand anderem kontrolliert wird, anstatt dass wir die Objekte explizit erstellen. Die Abhängigkeitsinjektion kann über eine Methode, einen Konstruktor oder ein Feld erfolgen. Weitere Einzelheiten finden Sie im CDI-Spezifikationskapitel „ 5.5. Abhängigkeitsinjektion “. Das Verfahren zur Bestimmung dessen, was implementiert werden muss, wird als typsichere Auflösung bezeichnet, worüber wir sprechen müssen.
Ein kurzer Ausflug in die Abhängigkeitsinjektion oder

Namensauflösung oder typsichere Auflösung

Typischerweise wird eine Schnittstelle als Typ des zu implementierenden Objekts verwendet, und der CDI-Container selbst bestimmt, welche Implementierung ausgewählt werden soll. Dies ist aus vielen Gründen nützlich, die wir diskutieren werden. Wir haben also eine Logger-Schnittstelle:
public interface Logger {
    void print(String message);
}
Er sagt, wenn wir einen Logger haben, können wir ihm eine Nachricht senden und er wird seine Aufgabe – das Loggen – erledigen. Wie und wo wird in diesem Fall nicht von Interesse sein. Erstellen wir nun eine Implementierung für den Logger:
public class SystemOutLogger implements Logger {
    @Inject
    private DateSource dateSource;

    public void print(String message) {
        System.out.println(message);
    }
}
Wie Sie sehen, handelt es sich hierbei um einen Logger, der in System.out schreibt. Wunderbar. Jetzt funktioniert unsere Hauptmethode wie zuvor. Logger logger = container.select(Logger.class).get(); Diese Zeile wird weiterhin vom Logger empfangen. Und das Schöne ist, dass wir nur die Schnittstelle kennen müssen und der CDI-Container sich bereits um die Implementierung kümmert. Nehmen wir an, wir haben eine zweite Implementierung, die das Protokoll irgendwo an einen Remote-Speicher senden soll:
public class NetworkLogger implements Logger {
    @Override
    public void print(String message) {
        System.out.println("Send log message to remote log system");
    }
}
Wenn wir nun unseren Code ohne Änderungen ausführen, erhalten wir eine Fehlermeldung, weil Der CDI-Container sieht zwei Implementierungen der Schnittstelle und kann nicht zwischen ihnen wählen: org.jboss.weld.exceptions.AmbiguousResolutionException: WELD-001335: Ambiguous dependencies for type Logger Was tun? Es stehen mehrere Varianten zur Verfügung. Die einfachste Möglichkeit ist die @Vetoed- Annotation für eine CDI-Bean, damit der CDI-Container diese Klasse nicht als CDI-Bean wahrnimmt. Aber es gibt einen viel interessanteren Ansatz. @AlternativeEine CDI-Bean kann mithilfe der im Kapitel „ 4.7. Alternativen “ der Weld CDI-Dokumentation beschriebenen Anmerkung als „Alternative“ markiert werden . Was bedeutet das? Das bedeutet, dass es nicht ausgewählt wird, es sei denn, wir sagen ausdrücklich, es zu verwenden. Dies ist eine alternative Version der Bohne. Markieren wir die NetworkLogger-Bean als @Alternative und wir können sehen, dass der Code erneut ausgeführt und von SystemOutLogger verwendet wird. Um die Alternative zu aktivieren, benötigen wir eine Beans.xml- Datei . Möglicherweise stellt sich die Frage: „ Beans.xml, wo soll ich sie hinstellen? “ Platzieren wir die Datei daher richtig:
Ein kurzer Ausflug in die Abhängigkeitsinjektion oder
Sobald wir diese Datei haben, wird das Artefakt mit unserem Code „ Explicit Bean Archive “ heißen. Jetzt haben wir zwei separate Konfigurationen: Software und XML. Das Problem besteht darin, dass sie dieselben Daten laden. Beispielsweise wird die DataSource-Bean-Definition zweimal geladen und unser Programm stürzt bei der Ausführung ab, weil Der CDI-Container betrachtet sie als zwei separate Beans (obwohl es sich tatsächlich um dieselbe Klasse handelt, von der der CDI-Container zweimal erfahren hat). Um dies zu vermeiden, gibt es zwei Möglichkeiten:
  • Entfernen Sie die Zeile initializer.addPackages(App.class.getPackage())und fügen Sie einen Hinweis auf die Alternative zur XML-Datei hinzu:
<beans
    xmlns="http://xmlns.jcp.org/xml/ns/javaee"
    xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
    xsi:schemaLocation="
        http://xmlns.jcp.org/xml/ns/javaee
        http://xmlns.jcp.org/xml/ns/javaee/beans_1_1.xsd">
    <alternatives>
        <class>ru.javarush.NetworkLogger</class>
    </alternatives>
</beans>
  • Fügen Sie dem Root-Element der Beans ein Attribut bean-discovery-modemit dem Wert „ none “ hinzu und geben Sie programmgesteuert eine Alternative an:
initializer.addPackages(App.class.getPackage());
initializer.selectAlternatives(NetworkLogger.class);
Somit kann der Container mithilfe der CDI-Alternative bestimmen, welche Bean ausgewählt werden soll. Wenn der CDI-Container mehrere Alternativen für dieselbe Schnittstelle kennt, können wir dies interessanterweise erkennen, indem wir die Priorität mithilfe einer Annotation angeben @Priority(seit CDI 1.1).
Ein kurzer Ausflug in die Abhängigkeitsinjektion oder

Qualifikanten

Unabhängig davon lohnt es sich, über Qualifikationsmerkmale zu sprechen. Der Qualifizierer wird durch eine Anmerkung über der Bean angezeigt und verfeinert die Suche nach der Bean. Und nun weitere Details. Interessanterweise verfügt jede CDI-Bean auf jeden Fall über mindestens ein Qualifikationsmerkmal – @Any. Wenn wir über der Bean KEINEN Qualifizierer angeben, fügt der CDI-Container selbst jedoch @Anyeinen weiteren Qualifizierer zum Qualifizierer hinzu – @Default. Wenn wir etwas angeben (z. B. explizit @Any angeben), wird der @Default-Qualifizierer nicht automatisch hinzugefügt. Aber das Schöne an Qualifiern ist, dass Sie Ihre eigenen Qualifier erstellen können. Das Qualifikationsmerkmal unterscheidet sich fast nicht von den Anmerkungen, weil Im Wesentlichen handelt es sich dabei lediglich um eine auf besondere Weise verfasste Anmerkung. Als Protokolltyp können Sie beispielsweise Enum eingeben:
public enum ProtocolType {
    HTTP, HTTPS
}
Als nächstes können wir einen Qualifizierer erstellen, der diesen Typ berücksichtigt:
@Qualifier
@Retention(RUNTIME)
@Target({METHOD, FIELD, PARAMETER, TYPE})
public @interface Protocol {
    ProtocolType value();
    @Nonbinding String comment() default "";
}
Es ist zu beachten, dass mit gekennzeichnete Felder @Nonbindingkeinen Einfluss auf die Bestimmung des Qualifizierers haben. Jetzt müssen Sie den Qualifizierer angeben. Es wird über dem Bean-Typ angezeigt (damit CDI weiß, wie es definiert wird) und über dem Injektionspunkt (mit der Annotation @Inject, damit Sie verstehen, nach welcher Bean Sie an dieser Stelle für die Injektion suchen müssen). Beispielsweise können wir eine Klasse mit einem Qualifikationsmerkmal hinzufügen. Der Einfachheit halber werden wir sie in diesem Artikel im NetworkLogger ausführen:
public interface Sender {
	void send(byte[] data);
}

@Protocol(ProtocolType.HTTP)
public static class HTTPSender implements Sender{
	public void send(byte[] data) {
		System.out.println("sended via HTTP");
	}
}

@Protocol(ProtocolType.HTTPS)
public static class HTTPSSender implements Sender{
	public void send(byte[] data) {
		System.out.println("sended via HTTPS");
	}
}
Und wenn wir dann „Inject“ ausführen, geben wir einen Qualifizierer an, der Einfluss darauf hat, welche Klasse verwendet wird:
@Inject
@Protocol(ProtocolType.HTTPS)
private Sender sender;
Großartig, nicht wahr?) Es scheint wunderschön, aber es ist unklar, warum. Stellen Sie sich nun Folgendes vor:
Protocol protocol = new Protocol() {
	@Override
	public Class<? extends Annotation> annotationType() {
		return Protocol.class;
	}
	@Override
	public ProtocolType value() {
		String value = "HTTP";
		return ProtocolType.valueOf(value);
	}
};
container.select(NetworkLogger.Sender.class, protocol).get().send(null);
Auf diese Weise können wir das Abrufen des Werts überschreiben, sodass dieser dynamisch berechnet werden kann. Es kann beispielsweise aus einigen Einstellungen übernommen werden. Dann können wir die Implementierung sogar im laufenden Betrieb ändern, ohne das Programm/den Server neu zu kompilieren oder neu zu starten. Es wird viel interessanter, nicht wahr? )
Ein kurzer Ausflug in die Abhängigkeitsinjektion oder

Produzenten

Eine weitere nützliche Funktion von CDI sind Produzenten. Dies sind spezielle Methoden (sie sind mit einer speziellen Annotation gekennzeichnet), die aufgerufen werden, wenn eine Bean eine Abhängigkeitsinjektion angefordert hat. Weitere Einzelheiten sind in der Dokumentation im Abschnitt „ 2.2.3. Produzentenmethoden “ beschrieben. Das einfachste Beispiel:
@Produces
public Integer getRandomNumber() {
	return new Random().nextInt(100);
}
Bei der Injektion in Felder vom Typ Integer wird nun diese Methode aufgerufen und daraus ein Wert ermittelt. Hier sollten wir sofort verstehen, dass wir, wenn wir das Schlüsselwort new sehen, sofort verstehen müssen, dass es sich NICHT um eine CDI-Bean handelt. Das heißt, eine Instanz der Random-Klasse wird nicht zu einer CDI-Bean, nur weil sie von etwas abgeleitet ist, das den CDI-Container steuert (in diesem Fall vom Produzenten).
Ein kurzer Ausflug in die Abhängigkeitsinjektion oder

Abfangjäger

Abfangjäger sind Abfangjäger, die sich in die Arbeit „einmischen“. Bei CDI geschieht dies ganz klar. Sehen wir uns an, wie wir die Protokollierung mithilfe von Interpretern (oder Interceptoren) durchführen können. Zuerst müssen wir die Bindung an den Abfangjäger beschreiben. Wie viele Dinge geschieht dies mithilfe von Anmerkungen:
@Inherited
@InterceptorBinding
@Target({TYPE, METHOD})
@Retention(RUNTIME)
public @interface ConsoleLog {
}
Die Hauptsache hier ist, dass es sich um eine Bindung für den Interceptor ( @InterceptorBinding) handelt, die von Extends () geerbt wird @InterceptorBinding. Schreiben wir nun den Interceptor selbst:
@Interceptor
@ConsoleLog
public class LogInterceptor {
    @AroundInvoke
    public Object log(InvocationContext ic) throws Exception {
        System.out.println("Invocation method: " + ic.getMethod().getName());
        return ic.proceed();
    }
}
Weitere Informationen zum Schreiben von Interceptoren finden Sie im Beispiel aus der Spezifikation: „ 1.3.6. Interceptor-Beispiel “. Nun, alles was wir tun müssen, ist den Inerceptor einzuschalten. Geben Sie dazu die Bindungsanmerkung über der auszuführenden Methode an:
@ConsoleLog
public void print(String message) {
Und nun noch ein weiteres sehr wichtiges Detail. Interceptoren sind standardmäßig deaktiviert und müssen auf die gleiche Weise wie die Alternativen aktiviert werden. Beispielsweise in der Datei „beans.xml“ :
<interceptors>
	<class>ru.javarush.LogInterceptor</class>
</interceptors>
Wie Sie sehen, ist es ganz einfach.
Ein kurzer Ausflug in die Abhängigkeitsinjektion oder

Ereignis & Beobachter

CDI bietet auch ein Modell von Ereignissen und Beobachtern. Hier ist nicht alles so offensichtlich wie bei Abfangjägern. Das Ereignis kann in diesem Fall also absolut jede Klasse sein; für die Beschreibung ist nichts Besonderes erforderlich. Zum Beispiel:
public class LogEvent {
    Date date = new Date();
    public String getDate() {
        return date.toString();
    }
}
Jetzt sollte jemand auf das Ereignis warten:
public class LogEventListener {
    public void logEvent(@Observes LogEvent event){
        System.out.println("Message Date: " + event.getDate());
    }
}
Hier geht es vor allem darum, die Annotation @Observes anzugeben, die angibt, dass es sich nicht nur um eine Methode handelt, sondern um eine Methode, die als Ergebnis der Beobachtung von Ereignissen vom Typ LogEvent aufgerufen werden soll. Nun brauchen wir jemanden, der zuschaut:
public class LogObserver {
    @Inject
    private Event<LogEvent> event;
    public void observe(LogEvent logEvent) {
        event.fire(logEvent);
    }
}
Wir haben eine einzige Methode, die dem Container mitteilt, dass ein Ereignisereignis für den Ereignistyp LogEvent aufgetreten ist. Jetzt müssen Sie nur noch den Beobachter verwenden. In NetworkLogger können wir beispielsweise eine Injektion unseres Beobachters hinzufügen:
@Inject
private LogObserver observer;
Und in der Druckmethode können wir den Beobachter darüber informieren, dass wir ein neues Ereignis haben:
public void print(String message) {
	observer.observe(new LogEvent());
Es ist wichtig zu wissen, dass Ereignisse in einem Thread oder in mehreren verarbeitet werden können. Verwenden Sie für die asynchrone Verarbeitung eine Methode .fireAsync(anstelle von .fire) und eine Annotation @ObservesAsync(anstelle von @Observes). Wenn beispielsweise alle Ereignisse in verschiedenen Threads ausgeführt werden und ein Thread eine Ausnahme auslöst, können die anderen ihre Arbeit für andere Ereignisse erledigen. Weitere Informationen zu Ereignissen in CDI finden Sie wie gewohnt in der Spezifikation im Kapitel „ 10. Ereignisse “.
Ein kurzer Ausflug in die Abhängigkeitsinjektion oder

Dekorateure

Wie wir oben gesehen haben, sind unter dem CDI-Flügel verschiedene Designmuster zusammengefasst. Und hier ist noch einer – ein Dekorateur. Das ist eine sehr interessante Sache. Werfen wir einen Blick auf diese Klasse:
@Decorator
public abstract class LoggerDecorator implements Logger {
    public final static String ANSI_GREEN = "\u001B[32m";
    public static final String ANSI_RESET = "\u001B[0m";

    @Inject
    @Delegate
    private Logger delegate;

    @Override
    public void print(String message) {
        delegate.print(ANSI_GREEN + message + ANSI_RESET);
    }
}
Indem wir es als Dekorator deklarieren, sagen wir, dass bei Verwendung einer Logger-Implementierung dieses „Add-on“ verwendet wird, das die tatsächliche Implementierung kennt, die im Delegate-Feld gespeichert ist (da es mit der Annotation markiert ist @Delegate). Dekoratoren können nur einer CDI-Bean zugeordnet werden, die selbst weder ein Interceptor noch ein Dekorator ist. Ein Beispiel ist auch in der Spezifikation zu sehen: „ 1.3.7. Decorator-Beispiel “. Der Decorator muss wie der Interceptor eingeschaltet sein. Zum Beispiel in Beans.xml :
<decorators>
	<class>ru.javarush.LoggerDecorator</class>
</decorators>
Weitere Einzelheiten finden Sie in der Schweißreferenz: „ Kapitel 10. Dekorateure “.

Lebenszyklus

Bohnen haben ihren eigenen Lebenszyklus. Es sieht ungefähr so ​​aus:
Ein kurzer Ausflug in die Abhängigkeitsinjektion oder
Wie Sie auf dem Bild sehen können, gibt es bei uns sogenannte Lifecycle-Callbacks. Hierbei handelt es sich um Annotationen, die den CDI-Container anweisen, in einer bestimmten Phase des Bean-Lebenszyklus bestimmte Methoden aufzurufen. Zum Beispiel:
@PostConstruct
public void init() {
	System.out.println("Inited");
}
Diese Methode wird aufgerufen, wenn eine CDI-Bean von einem Container instanziiert wird. Das Gleiche passiert mit @PreDestroy, wenn die Bean zerstört wird, wenn sie nicht mehr benötigt wird. Nicht umsonst enthält das Akronym CDI den Buchstaben C – Context. Beans in CDI sind kontextabhängig, was bedeutet, dass ihr Lebenszyklus vom Kontext abhängt, in dem sie im CDI-Container existieren. Um dies besser zu verstehen, sollten Sie den Spezifikationsabschnitt „ 7. Lebenszyklus kontextueller Instanzen “ lesen. Es ist auch wichtig zu wissen, dass der Container selbst einen Lebenszyklus hat, worüber Sie unter „ Container-Lebenszyklusereignisse “ nachlesen können.
Ein kurzer Ausflug in die Abhängigkeitsinjektion oder

Gesamt

Oben haben wir uns die Spitze des Eisbergs namens CDI angesehen. CDI ist Teil der JEE-Spezifikation und wird in der JavaEE-Umgebung verwendet. Wer Spring nutzt, nutzt nicht CDI, sondern DI, das heißt, das sind leicht unterschiedliche Spezifikationen. Aber wenn Sie das oben Gesagte kennen und verstehen, können Sie Ihre Meinung leicht ändern. Wenn man bedenkt, dass Spring Anmerkungen aus der CDI-Welt unterstützt (dasselbe Inject). Zusätzliche Materialien: #Wjatscheslaw
Kommentare
TO VIEW ALL COMMENTS OR TO MAKE A COMMENT,
GO TO FULL VERSION