为了初始化bean,我将枚举其他方法,我将该方法分组为标准方法和Spring Boot方法。
标准方法
-
@PostConstruct
:它只是一个在bean创建后触发方法的注释,它不允许输入参数。
-
@Bean(init-method="somInitMehotd")
:这种方法与Spring Bean生命周期完全相关,它是在Bean创建后调用的,如果您使用的是另一种带有注释的方法,那么将首先调用。此方法不允许输入参数。@PostConstruct
@PostConstruct
-
ApplicationListener
:此接口允许侦听与上下文生命周期相关的标准事件,也可以侦听自定义事件。例如:创建一个类,并在此情况下实现 will 实现一个接收MyAppListener
ApplicationListener<ContextRefreshedEvent>
MyAppListener
onApplicationEvent
ContextRefreshedEvent
弹簧靴方法
运行器:有两个非常有用的接口,它们都将在创建AdplicationContext后运行,它们都允许注入bean作为输入参数。CommandLineRunner
ApplicationRunner
Spring boot 侦听器:Spring 应用程序提供一些额外的事件,而不是来自应用程序上下文的标准事件。其中一个事件是,当应用程序准备好接收请求时,它将被触发。为了侦听此事件,只需将 using 实现为泛型。ApplicationReadyEvent
ApplicationListener
ApplicationReadyEvent
下面是一个示例:
MyBean 类具有不同的方法,这些方法将针对上面列出的每种方法调用,每个方法都将调用一个 print 方法,并且该方法具有 Thread.sleep,以便验证每个侦听器的调用顺序。
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();
}
}
}
下面是将侦听并处理它的类。ContextRefreshListener
ContextRefreshedEvent
public class ContextRefreshListener implements ApplicationListener<ContextRefreshedEvent> {
@Override
public void onApplicationEvent(ContextRefreshedEvent contextRefreshedEvent) {
contextRefreshedEvent.getApplicationContext().getBean(MyBean.class).contextInit();
}
}
它将从春季应用程序接收。BootListener
ApplicationReadyEvent
public class MyBootListener implements ApplicationListener<ApplicationReadyEvent> {
@Override
public void onApplicationEvent(ApplicationReadyEvent applicationReadyEvent) {
applicationReadyEvent.getApplicationContext().getBean(MyBean.class).bootListenerInit();
}
}
最后是弹簧启动应用程序
@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();
};
}
}
输出为:
Post init called
Bean init called
Context init called
Runner init called
Boot init called
Post init called
输出来自
@PostConstruct
public void init(){
this.initByPostconstruct="Post init called";
Bean init called
来自价值initMethod
@Bean(name = "myBean", initMethod = "beanInit")
public MyBean getMyBean(){
return new MyBean();
}
}
Context init called
来自ContextRefreshedEvent
public void onApplicationEvent(ContextRefreshedEvent contextRefreshedEvent) {
contextRefreshedEvent.getApplicationContext().getBean(MyBean.class).contextInit();
}
Runner init called
来自CommandLineRunner
@Bean
public CommandLineRunner getRunner(ApplicationContext ctx){
return (args) -> {
ctx.getBean(MyBean.class).runnerInit();
};
}
Boot init called
来自ApplicationReadyEvent
public void onApplicationEvent(ApplicationReadyEvent applicationReadyEvent) {
applicationReadyEvent.getApplicationContext().getBean(MyBean.class).bootListenerInit();
}
所有列出的场景都是由触发的,我没有直接调用任何事件,它们都是由.Spring
Spring Framework