Il existe plusieurs façons d'intercepter le processus d'initialisation dans Spring. Si vous devez initialiser tous les beans et les autowire / injecter, il y a au moins deux façons que je connaisse qui assureront cela. Je n'ai testé que le second mais je pense que les deux fonctionnent de la même manière.
Si vous utilisez @Bean, vous pouvez référencer par initMethod, comme ceci.
@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 vous utilisez @Component, vous pouvez annoter avec @EventListener comme ceci.
@Component
public class BeanB {
@EventListener
public void onApplicationEvent(ContextRefreshedEvent event) {
}
}
Dans mon cas, j'ai un système hérité dans lequel j'utilise maintenant IoC / DI où Spring Boot est le framework choisi. L'ancien système apporte de nombreuses dépendances circulaires à la table et je dois donc beaucoup utiliser la dépendance setter. Cela m'a donné des maux de tête car je ne pouvais pas faire confiance à @PostConstruct car l'autowiring / injection par setter n'était pas encore fait. L'ordre est constructeur, @PostConstruct puis setters autowired. Je l'ai résolu avec l'annotation @EventListener qui s'exécutera en dernier et en "même" temps pour tous les beans. L'exemple montre également l'implémentation d'InitializingBean.
J'ai deux classes (@Component) avec une dépendance l'une à l'autre. Les classes ont la même apparence dans le cadre de cet exemple en affichant une seule d'entre elles.
@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");
}
}
Il s'agit de la sortie du journal montrant l'ordre des appels lorsque le conteneur démarre.
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
Comme vous pouvez le voir, @EventListener est exécuté en dernier une fois que tout est prêt et configuré.