Hay varias formas de interceptar el proceso de inicialización en Spring. Si tiene que inicializar todos los beans y conectarlos automáticamente / inyectarlos, hay al menos dos formas que conozco que asegurarán esto. Solo he probado el segundo, pero creo que ambos funcionan igual.
Si está utilizando @Bean, puede hacer referencia mediante initMethod, así.
@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() {
}
}
Si está utilizando @Component, puede anotar con @EventListener de esta manera.
@Component
public class BeanB {
@EventListener
public void onApplicationEvent(ContextRefreshedEvent event) {
}
}
En mi caso, tengo un sistema heredado en el que ahora estoy usando IoC / DI donde Spring Boot es el marco elegido. El sistema antiguo trae muchas dependencias circulares a la tabla y, por lo tanto, debo usar mucho la dependencia del setter. Eso me dio algunos dolores de cabeza ya que no podía confiar en @PostConstruct ya que aún no se había realizado el cableado automático / inyección por parte del colocador. El orden es constructor, @PostConstruct y luego configuradores con cableado automático. Lo resolví con la anotación @EventListener que se ejecutará en último lugar y al "mismo" tiempo para todos los beans. El ejemplo también muestra la implementación de InitializingBean.
Tengo dos clases (@Component) con dependencia entre sí. Las clases tienen el mismo aspecto para el propósito de este ejemplo que muestra solo una de ellas.
@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 es la salida del registro que muestra el orden de las llamadas cuando se inicia el contenedor.
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 puede ver, @EventListener se ejecuta en último lugar después de que todo esté listo y configurado.