Esistono diversi modi per intercettare il processo di inizializzazione in Spring. Se devi inizializzare tutti i bean e autowire / iniettarli, ci sono almeno due modi che conosco per garantire ciò. Ho solo testato il secondo ma credo che entrambi funzionino allo stesso modo.
Se stai usando @Bean puoi fare riferimento tramite initMethod, in questo modo.
@Configuration
public class BeanConfiguration {
@Bean(initMethod="init")
public BeanA beanA() {
return new BeanA();
}
}
public class BeanA {
// method to be initialized after context is ready
public void init() {
}
}
Se stai usando @Component puoi annotare con @EventListener in questo modo.
@Component
public class BeanB {
@EventListener
public void onApplicationEvent(ContextRefreshedEvent event) {
}
}
Nel mio caso ho un sistema legacy in cui ora sto utilizzando IoC / DI in cui Spring Boot è il framework scelto. Il vecchio sistema porta molte dipendenze circolari alla tabella e quindi devo usare molto la dipendenza setter. Questo mi ha dato qualche grattacapo poiché non potevo fidarmi di @PostConstruct poiché l'autowiring / injection dal setter non era ancora stato fatto. L'ordine è costruttore, @PostConstruct quindi setter autowired. L'ho risolto con l'annotazione @EventListener che verrà eseguita per ultima e alla "stessa" ora per tutti i bean. L'esempio mostra anche l'implementazione di InitializingBean.
Ho due classi (@Component) dipendenti l'una dall'altra. Le classi hanno lo stesso aspetto ai fini di questo esempio che ne mostra solo una.
@Component
public class BeanA implements InitializingBean {
private BeanB beanB;
public BeanA() {
log.debug("Created...");
}
@PostConstruct
private void postConstruct() {
log.debug("@PostConstruct");
}
@Autowired
public void setBeanB(BeanB beanB) {
log.debug("@Autowired beanB");
this.beanB = beanB;
}
@Override
public void afterPropertiesSet() throws Exception {
log.debug("afterPropertiesSet()");
}
@EventListener
public void onApplicationEvent(ContextRefreshedEvent event) {
log.debug("@EventListener");
}
}
Questo è l'output del registro che mostra l'ordine delle chiamate all'avvio del contenitore.
2018-11-30 18:29:30.504 DEBUG 3624 --- [ main] com.example.demo.BeanA : Created...
2018-11-30 18:29:30.509 DEBUG 3624 --- [ main] com.example.demo.BeanB : Created...
2018-11-30 18:29:30.517 DEBUG 3624 --- [ main] com.example.demo.BeanB : @Autowired beanA
2018-11-30 18:29:30.518 DEBUG 3624 --- [ main] com.example.demo.BeanB : @PostConstruct
2018-11-30 18:29:30.518 DEBUG 3624 --- [ main] com.example.demo.BeanB : afterPropertiesSet()
2018-11-30 18:29:30.518 DEBUG 3624 --- [ main] com.example.demo.BeanA : @Autowired beanB
2018-11-30 18:29:30.518 DEBUG 3624 --- [ main] com.example.demo.BeanA : @PostConstruct
2018-11-30 18:29:30.518 DEBUG 3624 --- [ main] com.example.demo.BeanA : afterPropertiesSet()
2018-11-30 18:29:30.607 DEBUG 3624 --- [ main] com.example.demo.BeanA : @EventListener
2018-11-30 18:29:30.607 DEBUG 3624 --- [ main] com.example.demo.BeanB : @EventListener
Come puoi vedere @EventListener viene eseguito per ultimo dopo che tutto è pronto e configurato.