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-methodSind BeanPostProcessors.
@PostConstruct ist eine JSR-250-Annotation während init-method Spring eine Initialisierungsmethode verwendet.@PostConstructMethode haben, wird diese zuerst aufgerufen, bevor die Initialisierungsmethoden aufgerufen werden.afterPropertiesSet, wird zuerst @PostConstructaufgerufen, dann das afterPropertiesSetund 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-methodbeim 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:
@PostConstructdass aufgerufen wird.InitializingBeanimplementiert, afterPropertiesSet()wird aufgerufen.init-methododer @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 @PostConstructund init-methodweil @PostConstructin der Handhabung postProcessAfterInitializationPhase der Bohne Initialisierung ( AbstractAutowireCapableBeanFactory.initializeBean()Methode) durch CommonAnnotationBeanPostProcessor, während initVerfahren nach dem Abschluss der aufgerufen werden postProcessBeforeInitializationPhase (und, für diese Angelegenheit, vor dem Beginn der postProcessAfterInitializationPhase).
EDIT : Die Sequenz lautet also: 1) postProcessBeforeInitializationPhase, 2) initMethode wird aufgerufen, 3) postProcessAfterInitializationPhase, die aufruft@PostConstruct Methode
(Als Randnotiz eine Aussage aus der akzeptierten Antwort
@PostConstruct, init-Methode sind BeanPostProcessors
ist nicht ganz richtig: @PostConstructwird von a behandelt BeanPostProcessor, initMethode 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 postProcessBeforeInitializationMethode tun .
Es gibt keinen Unterschied zur Standard-Spring-Konfiguration von, BeanPostProcessorsda alle, die BeanPostProcessorsfü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]