Existem várias maneiras de interceptar o processo de inicialização no Spring. Se você tiver que inicializar todos os beans e autowire / injetá-los, há pelo menos duas maneiras que conheço que garantirão isso. Eu testei apenas o segundo, mas acredito que ambos funcionam da mesma forma.
Se você estiver usando @Bean, você pode fazer referência por initMethod, como este.
@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 estiver usando @Component, você pode anotar com @EventListener assim.
@Component
public class BeanB {
@EventListener
public void onApplicationEvent(ContextRefreshedEvent event) {
}
}
No meu caso, tenho um sistema legado onde agora estou usando IoC / DI, onde Spring Boot é a estrutura escolhida. O sistema antigo traz muitas dependências circulares para a tabela e, portanto, devo usar muito a dependência de setter. Isso me deu algumas dores de cabeça, já que não podia confiar em @PostConstruct, já que o autowiring / injeção por setter ainda não estava feito. O pedido é construtor, @PostConstruct e configuradores autowired. Resolvi isso com a anotação @EventListener que será executada por último e "ao mesmo" tempo para todos os beans. O exemplo mostra a implementação de InitializingBean também.
Eu tenho duas classes (@Component) com dependência uma da outra. As classes parecem iguais para o propósito deste exemplo, exibindo apenas uma delas.
@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");
}
}
Esta é a saída do log que mostra a ordem das chamadas quando o contêiner é iniciado.
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
Como você pode ver, @EventListener é executado por último depois que tudo estiver pronto e configurado.