Risposte:
No praticamente non penso ci sia alcuna differenza ma ci sono delle priorità nel modo in cui funzionano. @PostConstruct
, init-method
sono BeanPostProcessors.
@PostConstruct
è un'annotazione JSR-250 mentre init-method
è il modo in cui Spring ha un metodo di inizializzazione.@PostConstruct
metodo, questo verrà chiamato prima prima che vengano chiamati i metodi di inizializzazione.afterPropertiesSet
, prima @PostConstruct
viene chiamato, poi afterPropertiesSet
e 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 @PostConstruct
annotazioni per il mio codice (poiché il bean è configurato correttamente solo dopo che il metodo è stato chiamato) e lo uso init-method
quando 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:
@PostConstruct
sarà chiamato.InitializingBean
è implementato, afterPropertiesSet()
verrà chiamato.init-method
o @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 @PostConstruct
e init-method
perché @PostConstruct
viene gestita nella postProcessAfterInitialization
fase di inizializzazione fagiolo ( AbstractAutowireCapableBeanFactory.initializeBean()
metodo) da CommonAnnotationBeanPostProcessor
, mentre init
metodo viene chiamato dopo il completamento della postProcessBeforeInitialization
fase (e, per questa materia, prima dell'inizio della postProcessAfterInitialization
fase).
EDIT : Quindi, la sequenza è: 1) postProcessBeforeInitialization
fase, 2) init
metodo viene chiamato, 3) postProcessAfterInitialization
fase, che chiama @PostConstruct
metodo
(Come nota a margine, una dichiarazione dalla risposta accettata
@PostConstruct, init-method sono BeanPostProcessors
non è del tutto corretto: @PostConstruct
è gestito da un metodo BeanPostProcessor
, init
non 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 postProcessBeforeInitialization
metodo.
Non c'è alcuna differenza con la configurazione predefinita di Spring BeanPostProcessors
perché tutti quelli BeanPostProcessors
configurati per essere eseguiti dopo CommonAnnotationBeanPostProcessor
, non fanno nulla nel postProcessBeforeInitialization
metodo.
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]