Je vais énumérer d'autres approches afin d'initier les haricots, j'ai regroupé l'approche en Approche Standard et Approche Spring Boot.
Approche standard
-
@PostConstruct
il s'agit juste d'une annotation qui déclenche une méthode après la création du bean, elle n'autorise pas les paramètres d'entrée.
-
@Bean(init-method="somInitMehotd")
cette approche est totalement liée au cycle de vie du bean de Spring et est appelée après la création du bean, si vous utilisez une autre méthode avec @PostConstruct
l'annotation @PostConstruct
sera appelé en premier. Cette approche n'autorise pas les paramètres d'entrée.
-
ApplicationListener
Context Lifecycle : cette interface permet d'écouter les événements standard liés au cycle de vie du contexte, mais aussi des événements personnalisés. Par exemple : créer une classe MyAppListener
et met en œuvre ApplicationListener<ContextRefreshedEvent>
dans ce cas, le MyAppListener
mettra en œuvre un onApplicationEvent
qui reçoit un ContextRefreshedEvent
Approche de Spring Boot
-
Les coureurs : Il existe deux interfaces très utiles CommandLineRunner
y ApplicationRunner
les deux s'exécutent après la création de l'ApplicationContext les deux permettent d'injecter des beans comme paramètres d'entrée.
-
Écouteurs de Spring boot : Spring Application fournit des événements supplémentaires par rapport aux événements standards provenant du contexte de l'application. L'un de ces événements est ApplicationReadyEvent
et il est déclenché lorsque l'application est prête à recevoir une demande. Afin d'écouter ces événements, il suffit d'implémenter la fonction ApplicationListener
en utilisant ApplicationReadyEvent
comme générique.
Voici l'exemple :
La classe MyBean a différentes méthodes qui seront appelées pour chaque approche listée ci-dessus, chaque méthode appellera une méthode print et cette méthode a un Thread.sleep afin de valider l'ordre dans lequel chaque listener est appelé.
import javax.annotation.PostConstruct;
public class MyBean {
private String myVar="";
public MyBean(){
}
@PostConstruct
public void postConstructInit(){
this.myVar="Post init called";
print();
}
public void beanInit(){
this.myVar="Bean init called";
print();
}
public void contextInit(){
this.myVar="Context init called";
print();
}
public void runnerInit(){
this.myVar="Runner init called";
print();
}
public void bootListenerInit(){
this.myVar="Boot init called";
print();
}
public void print(){
System.out.println(this.myVar);
try {
Thread.sleep(3000);
} catch (InterruptedException e) {
e.printStackTrace();
}
}
}
Voici le ContextRefreshListener
qui écoutera le ContextRefreshedEvent
et le manipuler.
public class ContextRefreshListener implements ApplicationListener<ContextRefreshedEvent> {
@Override
public void onApplicationEvent(ContextRefreshedEvent contextRefreshedEvent) {
contextRefreshedEvent.getApplicationContext().getBean(MyBean.class).contextInit();
}
}
Et c'est le BootListener
qui recevra le ApplicationReadyEvent
qui provient de Spring Application.
public class MyBootListener implements ApplicationListener<ApplicationReadyEvent> {
@Override
public void onApplicationEvent(ApplicationReadyEvent applicationReadyEvent) {
applicationReadyEvent.getApplicationContext().getBean(MyBean.class).bootListenerInit();
}
}
Et enfin l'application Spring Boot
@SpringBootApplication
public class StackoverflowBootApplication {
public static void main(String[] args) {
SpringApplication.run(StackoverflowBootApplication.class, args);
}
@Bean(name = "myBean", initMethod = "beanInit")
public MyBean getMyBean(){
return new MyBean();
}
@Bean
public ContextRefreshListener getContextRefreshedListener(){return new ContextRefreshListener();}
@Bean
public MyBootListener getBootListener(){return new MyBootListener();}
@Bean
public CommandLineRunner getRunner(ApplicationContext ctx){
return (args) -> {
ctx.getBean(MyBean.class).runnerInit();
};
}
}
La sortie est :
Post init called
Bean init called
Context init called
Runner init called
Boot init called
Post init called
La sortie provient de
@PostConstruct
public void init(){
this.initByPostconstruct="Post init called";
Bean init called
vient de la initMethod
valeur
@Bean(name = "myBean", initMethod = "beanInit")
public MyBean getMyBean(){
return new MyBean();
}
}
Context init called
vient de ContextRefreshedEvent
public void onApplicationEvent(ContextRefreshedEvent contextRefreshedEvent) {
contextRefreshedEvent.getApplicationContext().getBean(MyBean.class).contextInit();
}
Runner init called
vient de CommandLineRunner
@Bean
public CommandLineRunner getRunner(ApplicationContext ctx){
return (args) -> {
ctx.getBean(MyBean.class).runnerInit();
};
}
Boot init called
vient de ApplicationReadyEvent
public void onApplicationEvent(ApplicationReadyEvent applicationReadyEvent) {
applicationReadyEvent.getApplicationContext().getBean(MyBean.class).bootListenerInit();
}
Tous les scénarios énumérés ont été déclenchés par Spring
je n'ai appelé aucun des événements directement, ils ont tous été appelés par Spring Framework
.