Antworten:
Nein, praktisch glaube ich nicht, dass es einen Unterschied gibt, aber es gibt Prioritäten in der Art und Weise, wie sie funktionieren. @PostConstruct
, init-method
Sind BeanPostProcessors.
@PostConstruct
ist eine JSR-250-Annotation während init-method
Spring eine Initialisierungsmethode verwendet.@PostConstruct
Methode haben, wird diese zuerst aufgerufen, bevor die Initialisierungsmethoden aufgerufen werden.afterPropertiesSet
, wird zuerst @PostConstruct
aufgerufen, dann das afterPropertiesSet
und dann init-method
.Weitere Informationen finden Sie in der Referenzdokumentation von Spring .
Vor den JSR 250-Spezifikationen wurde die Verwendung der init-Methode in XML bevorzugt, da Java-Klassen (Beans) von allen springspezifischen Klassen / Anmerkungen entkoppelt werden. Wenn Sie also eine Bibliothek erstellen, die nicht von Spring-Infrastruktur-Beans abhängig sein muss Dann wurde die Verwendung der Init-Methode bevorzugt. Während der Erstellungsmethode können Sie die Methode angeben, die als Initialisierungsmethode aufgerufen werden muss.
Mit der Einführung der JSR 250-Spezifikationen in Java EE und der Unterstützung dieser Anmerkungen durch Federn wurde die Abhängigkeit vom Federgerüst bis zu einem gewissen Grad verringert.
Aber ich muss zugeben, dass das Hinzufügen dieser Dinge die Lesbarkeit von Code erhöht. Es gibt also Vor- und Nachteile beider Ansätze.
Es gibt keinen wirklichen Unterschied. Es hängt davon ab, wie Sie Ihr System lieber konfigurieren, und das ist eine Frage der persönlichen Wahl. Ich selbst benutze es lieber@PostConstruct
Anmerkungen für meinen eigenen Code (da die Bean erst nach dem Aufruf der Methode korrekt konfiguriert wird) und verwende sie init-method
beim Instanziieren von Beans aus nicht Spring-fähigen Bibliotheken (dort können natürlich keine Anmerkungen angewendet werden!). Aber ich kann die Leute total verstehen, die alles auf die eine oder andere Weise machen wollen.
@postconstruct ist nicht Teil des Frühlings. Es ist Teil des Javax-Pakets. Beide sind gleich. Mit der Init-Methode müssen wir in XML-Datei hinzufügen. Wenn Sie @postconstruct verwenden, ist das Hinzufügen in XML nicht erforderlich. Lesen Sie den folgenden Artikel.
Wie Sie im folgenden Diagramm von Bean Creation Life-Cycle Callback sehen können .
Dieser dreistufige Schritt erfolgt im Bean Creation Life-Cycle Callback:
@PostConstruct
dass aufgerufen wird.InitializingBean
implementiert, afterPropertiesSet()
wird aufgerufen.init-method
oder @Bean(initmethod="..")
dann die init-Methode aufruft.Dieses Diagramm stammt aus Pro Spring 5: Eine ausführliche Anleitung zum Spring Framework und seinen Tools
Es könnte seinen Unterschied zwischen @PostConstruct
und init-method
weil @PostConstruct
in der Handhabung postProcessAfterInitialization
Phase der Bohne Initialisierung ( AbstractAutowireCapableBeanFactory.initializeBean()
Methode) durch CommonAnnotationBeanPostProcessor
, während init
Verfahren nach dem Abschluss der aufgerufen werden postProcessBeforeInitialization
Phase (und, für diese Angelegenheit, vor dem Beginn der postProcessAfterInitialization
Phase).
EDIT : Die Sequenz lautet also: 1) postProcessBeforeInitialization
Phase, 2) init
Methode wird aufgerufen, 3) postProcessAfterInitialization
Phase, die aufruft@PostConstruct
Methode
(Als Randnotiz eine Aussage aus der akzeptierten Antwort
@PostConstruct, init-Methode sind BeanPostProcessors
ist nicht ganz richtig: @PostConstruct
wird von a behandelt BeanPostProcessor
, init
Methode nicht.)
Es wird einen Unterschied geben, ob einige (möglicherweise benutzerdefinierte) BeanPostProcessor
, die mit ( Ordered.getOrder()
) konfiguriert sind , um danach ausgeführt zu werden CommonAnnotationBeanPostProcessor
, etwas Ernstes in ihrer postProcessBeforeInitialization
Methode tun .
Es gibt keinen Unterschied zur Standard-Spring-Konfiguration von, BeanPostProcessors
da alle, die BeanPostProcessors
für die Ausführung nach konfiguriert sind CommonAnnotationBeanPostProcessor
, nichts tunpostProcessBeforeInitialization
Methode .
Zusammenfassend ist die akzeptierte Antwort und dergleichen richtig ... in 99% der Fälle, und dieser Beitrag ist nur eine Hommage an ein Konzept "Der Teufel steckt im Detail".
Vollständiger Code hier: https://github.com/wkaczurba/so8519187 ( Spring-Boot )
Verwenden von Anmerkungen:
@Slf4j
@Component
public class MyComponent implements InitializingBean {
@Value("${mycomponent.value:Magic}")
public String value;
public MyComponent() {
log.info("MyComponent in constructor: [{}]", value); // (0) displays: Null
}
@PostConstruct
public void postConstruct() {
log.info("MyComponent in postConstruct: [{}]", value); // (1) displays: Magic
}
@Override // init-method; overrides InitializingBean.afterPropertiesSet()
public void afterPropertiesSet() {
log.info("MyComponent in afterPropertiesSet: [{}]", value); // (2) displays: Magic
}
@PreDestroy
public void preDestroy() {
log.info("MyComponent in preDestroy: [{}]", value); // (3) displays: Magic
}
}
Erhält uns:
Aktualisieren von org.springframework.context ...
MyComponent im Konstruktor: [null]
MyComponent in postConstruct: [Magic]
MyComponent in afterPropertiesSet: [Magic]
...
Registrieren von Beans für JMX-Exposition beim Start
Started DemoApplication in 0,561 Sekunden (JVM läuft für 1.011)
Schließen von org.springframework.context .. Aufheben der Registrierung von JMX-exponierten Beans beim Herunterfahren
...
MyComponent in preDestroy: [Magic]