Java Spring Boot 在初始化时添加业务逻辑

1. ApplicationListener<ContextRefreshedEvent>

Spring 内置的事件

  1. ContextRefreshedEventApplicationContext 被初始化或刷新时,该事件被发布。这也可以在 ConfigurableApplicationContext 接口中使用 refresh() 方法来发生。此处的初始化是指:所有的Bean被成功装载,后处理Bean被检测并激活,所有 Singleton Bean 被预实例化,``ApplicationContext容器已就绪可用。
  2. ContextStartedEvent:当使用 ConfigurableApplicationContext (ApplicationContext子接口)接口中的 start() 方法启动 ApplicationContext 时,该事件被发布。你可以调查你的数据库,或者你可以在接受到这个事件后重启任何停止的应用程序。
  3. ContextStoppedEvent:当使用 ConfigurableApplicationContext 接口中的 stop() 停止 ApplicationContext 时,发布这个事件。你可以在接受到这个事件后做必要的清理的工作。
  4. ContextClosedEvent:当使用 ConfigurableApplicationContext 接口中的 close() 方法关闭 ApplicationContext 时,该事件被发布。一个已关闭的上下文到达生命周期末端;它不能被刷新或重启。
  5. RequestHandledEvent:这是一个 web-specific 事件,告诉所有 bean HTTP 请求已经被服务。只能应用于使用 DispatcherServlet 的Web应用。在使用Spring作为前端的MVC控制器时,当Spring处理用户请求结束后,系统会自动触发该事件。

代码实例:

1
2
3
4
5
6
7
8
@Component
public class TestApplicationListener implements ApplicationListener<ContextRefreshedEvent>{
@Override
public void onApplicationEvent(ContextRefreshedEvent contextRefreshedEvent) {
System.out.println(contextRefreshedEvent);
System.out.println("TestApplicationListener............................");
}
}

可以自定义事件完成一些特定请求

  1. 自定义 EmailEvent
1
2
3
4
5
6
7
8
9
10
11
12
13
public class EmailEvent extends ApplicationEvent{
   private String address;
   private String text;
   public EmailEvent(Object source, String address, String text){
   super(source);
      this.address = address;
      this.text = text;
   }
   public EmailEvent(Object source) {
     super(source);
   }
   //......address和text的setter、getter
}
  1. 自定义监听器
1
2
3
4
5
6
7
8
9
10
11
public class EmailNotifier implements ApplicationListener{
   public void onApplicationEvent(ApplicationEvent event) {
     if (event instanceof EmailEvent) {
        EmailEvent emailEvent = (EmailEvent)event;
        System.out.println("邮件地址:" + emailEvent.getAddress());
        System.our.println("邮件内容:" + emailEvent.getText());
     } else {
        System.our.println("容器本身事件:" + event);
     }
   }
}
  1. 发送邮件后,触发事件
1
2
3
4
5
6
7
8
9
public class SpringTest {
   public static void main(String args[]){
     ApplicationContext context = new ClassPathXmlApplicationContext("bean.xml");
     //创建一个ApplicationEvent对象
     EmailEvent event = new EmailEvent("hello","abc@163.com","This is a test");
     //主动触发该事件
     context.publishEvent(event);
   }
}

2. Spring Boot 的 CommandLineRunner 接口

1
2
3
4
5
6
7
8
9
10
11
12
@Component
@Slf4j
public class CustomCommandLineRunner implements CommandLineRunner {

/**
* @param args 接收控制台传入的参数
*/
@Override
public void run(String... args) throws Exception {
log.debug("从控制台接收参数>>>>"+ Arrays.asList(args));
}
}

3. Spring Boot 的 ApplicationRunner 接口

ApplicationRunnerCommandLineRunner都是Spring Boot 提供的,相对于CommandLineRunner来说对于控制台传入的参数封装更好一些,可以通过键值对来获取指定的参数,比如 --version=1

4. @PostConstruct

针对 Bean 初始化完成后做一些事情

1
2
3
4
5
6
7
8
9
@Component
@Slf4j
public class SimpleExampleBean {

@PostConstruct
public void init(){
log.debug("Bean初始化完成,调用...........");
}
}

5. @Bean注解中指定初始化方法

1
2
3
4
5
6
7
8
9
10
11
12
@Slf4j
public class SimpleExampleBean {

public void init(){
log.debug("Bean初始化完成,调用...........");
}
}

@Bean(initMethod = "init")
public SimpleExampleBean simpleExampleBean(){
return new SimpleExampleBean();
}

6. InitializingBean 接口

InitializingBean的用法基本上与@PostConstruct一致,只不过相应的Bean需要实现afterPropertiesSet方法

1
2
3
4
5
6
7
8
9
@Slf4j
@Component
public class SimpleExampleBean implements InitializingBean {

@Override
public void afterPropertiesSet() {
log.debug("Bean初始化完成,调用...........");
}
}