Ich studiere für die Spring Core-Zertifizierung und habe einige Zweifel daran, wie Spring mit dem Bohnen-Lebenszyklus und insbesondere mit dem Bohnen-Postprozessor umgeht .
Also habe ich dieses Schema:
Mir ist ziemlich klar, was es bedeutet:
Die folgenden Schritte finden in der Phase Load Bean-Definitionen statt :
Die @ Configuration- Klassen werden verarbeitet und / oder @Components werden durchsucht und / oder XML-Dateien werden analysiert.
BeanFactory hinzugefügte Bean-Definitionen (jede unter ihrer ID indiziert)
Besondere BeanFactoryPostProcessor- Beans, die aufgerufen werden, können die Definition jeder Bean ändern (z. B. für das Ersetzen von Eigenschaftsplatzhalterwerten).
Dann finden die folgenden Schritte in der statt Phase :
Jede Bean wird standardmäßig eifrig instanziiert (in der richtigen Reihenfolge mit eingespeisten Abhängigkeiten erstellt).
Nach der Abhängigkeitsinjektion durchläuft jede Bean eine Nachbearbeitungsphase, in der eine weitere Konfiguration und Initialisierung erfolgen kann.
Nach der Nachbearbeitung ist die Bean vollständig initialisiert und einsatzbereit (wird anhand ihrer ID verfolgt, bis der Kontext zerstört ist).
Ok, das ist mir ziemlich klar und ich weiß auch, dass es zwei Arten von Bean-Postprozessoren gibt:
Initialisierer: Initialisieren Sie die Bean, wenn Sie dazu aufgefordert werden (dh @PostConstruct).
und alles andere: Diese ermöglichen eine zusätzliche Konfiguration und können vor oder nach dem Initialisierungsschritt ausgeführt werden
Und ich poste diese Folie:
Es ist mir also sehr klar, was die Initialisierer bewirken Bean- Postprozessoren tun (dies sind die mit @ PostContruct- Annotation annotierten Methoden , die automatisch unmittelbar nach den Setter-Methoden (also nach der Abhängigkeitsinjektion) aufgerufen werden, und ich weiß, dass ich sie verwenden kann Führen Sie einen Initialisierungsstapel durch (füllen Sie einen Cache wie im vorherigen Beispiel).
Aber was genau repräsentiert den anderen Bean-Postprozessor? Was meinen wir, wenn wir sagen, dass diese Schritte ausgeführt werden? vor oder nach der Initialisierungsphase ausgeführt werden ?
Meine Beans werden instanziiert und ihre Abhängigkeiten werden injiziert, sodass die Initialisierungsphase abgeschlossen ist (durch Ausführen einer mit @PostContruct annotierten Methode). Was meinen wir damit, dass vor der Initialisierungsphase ein Bean-Postprozessor verwendet wird? Es bedeutet, dass es vor dem passiert @PostContruct kommentierten Methodenausführung ? Bedeutet dies, dass dies vor der Abhängigkeitsinjektion geschehen könnte (bevor die Setter-Methoden aufgerufen werden)?
Und was genau meinen wir, wenn wir sagen, dass es nach dem Initialisierungsschritt ausgeführt wird . Dies bedeutet, dass danach eine mit @PostContruct annotierte Methode ausgeführt wird, oder was?
Ich kann mir leicht vorstellen, warum ich eine mit @PostContruct kommentierte Methode benötige , aber ich kann kein typisches Beispiel für die andere Art von Bean- Postprozessor finden. Können Sie mir ein typisches Beispiel für die Verwendung zeigen?
quelle
Antworten:
Spring doc erläutert die BPPs unter Anpassen von Beans mit BeanPostProcessor . BPP-Beans sind eine spezielle Art von Beans, die vor allen anderen Beans erstellt werden und mit neu erstellten Beans interagieren. Mit diesem Konstrukt können Sie mit Spring das Lebenszyklusverhalten einfach durch Implementieren von a verbinden und anpassen
BeanPostProcessor
.Mit einem benutzerdefinierten BPP wie
würde aufgerufen werden und den Klassen- und Bean-Namen für jede erstellte Bean ausdrucken.
Um zu verstehen, wie die Methode zum Lebenszyklus der Bean passt und wann genau die Methode aufgerufen wird, überprüfen Sie die Dokumente
Das Wichtige ist auch das
Was die Beziehung zu dem
@PostConstruct
Hinweis betrifft , dass diese Annotation eine bequeme Methode zum Deklarieren einerpostProcessAfterInitialization
Methode ist, wird Spring darauf aufmerksam, wenn Sie entwederCommonAnnotationBeanPostProcessor
die<context:annotation-config />
In-Bean-Konfigurationsdatei registrieren oder angeben . Ob die@PostConstruct
Methode vor oder nach einer anderen Methode ausgeführt wird,postProcessAfterInitialization
hängt von derorder
Eigenschaft abquelle
Das typische Beispiel für einen Bean-Postprozessor ist, wenn Sie die ursprüngliche Bean in eine Proxy-Instanz einschließen möchten, z. B. wenn Sie die verwenden
@Transactional
Annotation verwenden.Dem Bean-Postprozessor wird die ursprüngliche Instanz der Bean übergeben. Er kann beliebige Methoden auf dem Ziel aufrufen, kann aber auch die tatsächliche Bean-Instanz zurückgeben, die im Anwendungskontext gebunden werden soll, was bedeutet, dass er tatsächlich eine beliebige zurückgeben kann Objekt, das es will. Das typische Szenario, in dem dies nützlich ist, besteht darin, dass der Bean-Postprozessor das Ziel in eine Proxy-Instanz einschließt. Alle Aufrufe auf der Bean, die im Anwendungskontext gebunden sind, werden über den Proxy geleitet, und der Proxy kann vor und / oder nach Aufrufen auf der Ziel-Bean, z. B. AOP oder Transaktionsverwaltung, etwas Magie ausführen.
quelle
Der Unterschied besteht darin, dass
BeanPostProcessor
die Kontextinitialisierung aktiviertpostProcessBeforeInitialization
und dannpostProcessAfterInitialization
für alle definierten Beans aufgerufen wird .Wird
@PostConstruct
jedoch nur für die bestimmte Klasse verwendet, für die Sie die Bean-Erstellung nach dem Konstruktor oder der Set-Methode anpassen möchten.quelle