Risposte:
No praticamente non penso ci sia alcuna differenza ma ci sono delle priorità nel modo in cui funzionano. @PostConstruct, init-methodsono BeanPostProcessors.
@PostConstructè un'annotazione JSR-250 mentre init-methodè il modo in cui Spring ha un metodo di inizializzazione.@PostConstructmetodo, questo verrà chiamato prima prima che vengano chiamati i metodi di inizializzazione.afterPropertiesSet, prima @PostConstructviene chiamato, poi afterPropertiesSete poi init-method.Per maggiori informazioni puoi controllare la documentazione di riferimento di Spring .
Prima delle specifiche JSR 250, l'uso del metodo init in xml era il modo preferito, in quanto disaccoppia le classi java (bean) da qualsiasi classe / annotazione specifica della primavera, quindi se stai costruendo una libreria che non ha bisogno di dipendere dai bean dell'infrastruttura della primavera quindi è stato preferito l'uso del metodo init. Durante la creazione del metodo è possibile specificare il metodo che deve essere chiamato come metodo di inizializzazione.
Ora con l'introduzione delle specifiche JSR 250 in Java EE e il supporto Spring di queste annotazioni, la dipendenza dal framework Spring è stata ridotta in una certa misura.
Ma devo ammettere che l'aggiunta di queste cose aumenta la leggibilità del codice, quindi ci sono pro e contro entrambi gli approcci.
Non c'è vera differenza. Dipende da come preferisci configurare il tuo sistema, ed è una questione di scelta personale. Io stesso, preferisco usare le @PostConstructannotazioni per il mio codice (poiché il bean è configurato correttamente solo dopo che il metodo è stato chiamato) e lo uso init-methodquando instanzio i bean da librerie non compatibili con Spring (non posso applicare annotazioni lì, ovviamente!) ma posso capire totalmente le persone che vogliono fare tutto in un modo o nell'altro.
@postconstruct non fa parte della primavera. Fa parte del pacchetto javax. Entrambi sono la stessa cosa. usando il metodo init dobbiamo aggiungere nel file xml. Se usi @postconstruct, l'aggiunta in xml non è richiesta. Dai un'occhiata all'articolo qui sotto.
Come puoi vedere nel diagramma sottostante di Bean Creation Life-Cycle Callback .
Questo 3 passaggio si verifica nel callback del ciclo di vita della creazione di fagioli:
@PostConstructsarà chiamato.InitializingBeanè implementato, afterPropertiesSet()verrà chiamato.init-methodo @Bean(initmethod="..")allora chiama il metodo init.Questo diagramma è tratto da Pro Spring 5: una guida approfondita a Spring Framework e ai suoi strumenti
Ci potrebbe essere differenza tra @PostConstructe init-methodperché @PostConstructviene gestita nella postProcessAfterInitializationfase di inizializzazione fagiolo ( AbstractAutowireCapableBeanFactory.initializeBean()metodo) da CommonAnnotationBeanPostProcessor, mentre initmetodo viene chiamato dopo il completamento della postProcessBeforeInitializationfase (e, per questa materia, prima dell'inizio della postProcessAfterInitializationfase).
EDIT : Quindi, la sequenza è: 1) postProcessBeforeInitializationfase, 2) initmetodo viene chiamato, 3) postProcessAfterInitializationfase, che chiama @PostConstructmetodo
(Come nota a margine, una dichiarazione dalla risposta accettata
@PostConstruct, init-method sono BeanPostProcessors
non è del tutto corretto: @PostConstructè gestito da un metodo BeanPostProcessor, initnon lo è.)
Ci sarà differenza se alcuni (potenzialmente personalizzati) BeanPostProcessor, che sono configurati con ( Ordered.getOrder()) per essere eseguiti dopo CommonAnnotationBeanPostProcessor, stanno facendo qualcosa di serio nel suo postProcessBeforeInitializationmetodo.
Non c'è alcuna differenza con la configurazione predefinita di Spring BeanPostProcessorsperché tutti quelli BeanPostProcessorsconfigurati per essere eseguiti dopo CommonAnnotationBeanPostProcessor, non fanno nulla nel postProcessBeforeInitializationmetodo.
In conclusione, la risposta accettata e simili sono giuste ... nel 99% dei casi, e questo post è solo per rendere omaggio a un concetto "il diavolo è nei dettagli"
Codice completo qui: https://github.com/wkaczurba/so8519187 ( spring-boot )
Utilizzo delle annotazioni:
@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
}
}
Ci ottiene:
Aggiornamento di org.springframework.context in corso ...
MyComponent nel costruttore: [null]
MyComponent in postConstruct: [Magic]
MyComponent in afterPropertiesSet: [Magic]
...
Registrazione dei bean per l'esposizione JMX all'avvio
DemoApplication avviata in 0,561 secondi (JVM in esecuzione per 1.011)
Chiusura org.springframework.context .. Annullamento della registrazione dei bean esposti a JMX allo spegnimento
...
MyComponent in preDestroy: [Magic]