我需要在应用程序启动后在Spring上下文中初始化bean; 目前,我使用注释@Configuration在类中初始化bean,如下所示:
@Configuration
public class AppConfig {
@Inject
@Bean
public BeanA init(param1, param2, etc...) {
--- Code to construct bean A ---
}
@Inject
@Bean
public BeanB init(param1, param2, etc...) {
--- Code to construct bean B ---
}
}
Run Code Online (Sandbox Code Playgroud)
但是我需要在应用程序启动后初始化一些bean,所以我的方法是创建一个类,在Spring中监听ApplicationReadyEvent事件,并将代码初始化为该类中的bean.
@Configuration
class ApplicationStartingListener implements ApplicationListener<ApplicationReadyEvent>{
---- Code to init bean here ----
@Override
public void onApplicationEvent(ApplicationReadyEvent event) {
--- If I put init bean code in here, is it correct? ----
}
}
Run Code Online (Sandbox Code Playgroud)
这是最好的方法吗?还是有其他更好的解决方案?
Dan*_* C. 42
我将枚举其他方法以初始化bean,我将方法分为标准方法和Spring Boot方法.
标准方法
@PostConstruct
:它只是一个在创建bean后触发方法的注释,它不允许输入参数.@Bean(init-method="somInitMehotd")
:这种方法与Spring bean生命周期完全相关,并且在创建bean之后调用它,如果你使用另一个带@PostConstruct
注释的方法,那么@PostConstruct
将首先调用它.此方法不允许输入参数.ApplicationListener
:此界面允许侦听与上下文生命周期相关的标准事件,也可以侦听自定义事件.例如:创建一个类MyAppListener
并ApplicationListener<ContextRefreshedEvent>
在这种情况下实现MyAppListener
将实现一个onApplicationEvent
接收a 的方法ContextRefreshedEvent
春靴方法
该参赛者:有两个非常有用的接口CommandLineRunner
,并ApplicationRunner
在创建后的ApplicationContext他们都可以注入豆作为输入参数他们都将运行.
Spring引导侦听器:Spring Application提供了一些额外的事件,而不是来自Application Context的标准事件.其中一个事件是ApplicationReadyEvent
,当应用程序准备好接收请求时它就会触发.为了监听这些事件,只需将ApplicationListener
using 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();
}
}
}
Run Code Online (Sandbox Code Playgroud)
这是ContextRefreshListener
将听取ContextRefreshedEvent
并处理它的类.
public class ContextRefreshListener implements ApplicationListener<ContextRefreshedEvent> {
@Override
public void onApplicationEvent(ContextRefreshedEvent contextRefreshedEvent) {
contextRefreshedEvent.getApplicationContext().getBean(MyBean.class).contextInit();
}
}
Run Code Online (Sandbox Code Playgroud)
它是BootListener
将接收ApplicationReadyEvent
的是来自Spring应用程序.
public class MyBootListener implements ApplicationListener<ApplicationReadyEvent> {
@Override
public void onApplicationEvent(ApplicationReadyEvent applicationReadyEvent) {
applicationReadyEvent.getApplicationContext().getBean(MyBean.class).bootListenerInit();
}
}
Run Code Online (Sandbox Code Playgroud)
最后是Spring Boot Application
@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();
};
}
}
Run Code Online (Sandbox Code Playgroud)
输出是:
Post init called
Bean init called
Context init called
Runner init called
Boot init called
Run Code Online (Sandbox Code Playgroud)
Post init called
输出来自
@PostConstruct
public void init(){
this.initByPostconstruct="Post init called";
Run Code Online (Sandbox Code Playgroud)
Bean init called
来自initMethod
价值
@Bean(name = "myBean", initMethod = "beanInit")
public MyBean getMyBean(){
return new MyBean();
}
}
Run Code Online (Sandbox Code Playgroud)
Context init called
来自 ContextRefreshedEvent
public void onApplicationEvent(ContextRefreshedEvent contextRefreshedEvent) {
contextRefreshedEvent.getApplicationContext().getBean(MyBean.class).contextInit();
}
Run Code Online (Sandbox Code Playgroud)
Runner init called
来自 CommandLineRunner
@Bean
public CommandLineRunner getRunner(ApplicationContext ctx){
return (args) -> {
ctx.getBean(MyBean.class).runnerInit();
};
}
Run Code Online (Sandbox Code Playgroud)
Boot init called
来自 ApplicationReadyEvent
public void onApplicationEvent(ApplicationReadyEvent applicationReadyEvent) {
applicationReadyEvent.getApplicationContext().getBean(MyBean.class).bootListenerInit();
}
Run Code Online (Sandbox Code Playgroud)
所有列出的场景都是由Spring
我触发的,我没有直接调用任何事件,所有这些事件都被调用了Spring Framework
.
归档时间: |
|
查看次数: |
34042 次 |
最近记录: |