gpt4 book ai didi

java - 应用程序启动后在 Spring 上下文中初始化 bean 的最佳方法?

转载 作者:IT老高 更新时间:2023-10-28 13:55:53 26 4
gpt4 key购买 nike

我需要在我的应用程序启动后在 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 ---
}
}

但是我需要在应用程序启动后初始化一些 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? ----
}
}

这是最好的方法吗?还是有其他更好的解决方案?

最佳答案

我将列举其他方法来初始化 bean,我将这些方法分为标准方法和 Spring Boot 方法。

标准方法

  1. @PostConstruct : 只是创建bean后触发方法的注解,不允许输入参数。
  2. @Bean(init-method="somInitMehotd") :这种方法与 Spring bean 生命周期完全相关,它在 bean 创建后调用,如果您使用其他方法,@PostConstruct注释,然后是 @PostConstruct将首先被调用。这种方法不允许输入参数。
  3. ApplicationListener :该接口(interface)允许监听与上下文生命周期相关的标准事件,也可以监听自定义事件。例如:创建一个类MyAppListener并实现 ApplicationListener<ContextRefreshedEvent>在这种情况下 MyAppListener将实现 onApplicationEvent接收 ContextRefreshedEvent 的方法

Spring Boot 方法

  1. 跑者:有两个非常有用的接口(interface)CommandLineRunnerApplicationRunner它们都将在 ApplicationContext 创建后运行它们都允许注入(inject) bean 作为输入参数。

  2. Spring 启动监听器:Spring 应用程序提供了一些额外的事件,而不是来自应用程序上下文的标准事件。其中一个事件是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来自 Spring Application。

public class MyBootListener implements ApplicationListener<ApplicationReadyEvent> {
@Override
public void onApplicationEvent(ApplicationReadyEvent applicationReadyEvent) {
applicationReadyEvent.getApplicationContext().getBean(MyBean.class).bootListenerInit();
}
}

最后是 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();
};
}

}

输出是:

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值(value)

@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调用的.

关于java - 应用程序启动后在 Spring 上下文中初始化 bean 的最佳方法?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/45747933/

26 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com