Spring Boot 启动事件和监听器,太强大了!

简介: 大家都知道,在 Spring 框架中事件和监听无处不在,打通了 Spring 框架的任督二脉,事件和监听也是 Spring 框架必学的核心知识之一。

大家都知道,在 Spring 框架中事件和监听无处不在,打通了 Spring 框架的任督二脉,事件和监听也是 Spring 框架必学的核心知识之一。


一般来说,我们很少会使用到应用程序事件,但我们也不要忘了它们的存在,比如说在 Spring 框架内部都使用了各种不同的事件来处理不同的任务。


毫无疑问,在 Spring Boot 框架中,事件和监听也得到了发扬光大,除了常用的 Spring Framework 事件(例如:ContextRefreshedEvent)之外,Spring Boot 在启动过程中还发送一系列其他的应用程序事件。


Spring Boot 启动事件顺序

1、ApplicationStartingEvent


这个事件在 Spring Boot 应用运行开始时,且进行任何处理之前发送(除了监听器和初始化器注册之外)。


2、ApplicationEnvironmentPreparedEvent


这个事件在当已知要在上下文中使用 Spring 环境(Environment)时,在 Spring 上下文(context)创建之前发送。


3、ApplicationContextInitializedEvent


这个事件在当 Spring 应用上下文(ApplicationContext)准备好了,并且应用初始化器(ApplicationContextInitializers)已经被调用,在 bean 的定义(bean definitions)被加载之前发送。


4、ApplicationPreparedEvent


这个事件是在 Spring 上下文(context)刷新之前,且在 bean 的定义(bean definitions)被加载之后发送。


5、ApplicationStartedEvent


这个事件是在 Spring 上下文(context)刷新之后,且在 application/ command-line runners 被调用之前发送。


6、AvailabilityChangeEvent


这个事件紧随上个事件之后发送,状态:ReadinessState.CORRECT,表示应用已处于活动状态。


7、ApplicationReadyEvent


这个事件在任何 application/ command-line runners 调用之后发送。


8、AvailabilityChangeEvent


这个事件紧随上个事件之后发送,状态:ReadinessState.ACCEPTING_TRAFFIC,表示应用可以开始准备接收请求了。


9、ApplicationFailedEvent


这个事件在应用启动异常时进行发送。


上面所介绍的这些事件列表仅包括绑定到 SpringApplication 的 SpringApplicationEvents 事件,除了这些事件以外,以下事件也会在 ApplicationPreparedEvent 之后和 ApplicationStartedEvent 之前发送:


WebServerInitializedEvent


这个 Web 服务器初始化事件在 WebServer 启动之后发送,对应的还有 ServletWebServerInitializedEvent(Servlet Web 服务器初始化事件)、ReactiveWebServerInitializedEvent(响应式 Web 服务器初始化事件)。


ContextRefreshedEvent


这个上下文刷新事件是在 Spring 应用上下文(ApplicationContext)刷新之后发送。


自定义启动事件监听器

既然我们知道了 Spring Boot 在启动过程中的各个事件,那么我们就可以在每个环节来处理一些我们想做的事情,只需要自定义一个监听器来监听某个事件就可以了。


比如我们想在上面的第 8 步,即应用启动完成可以接收请求了,我们简单输出一个成功标识。


Spring Boot 基础的构建这里就不介绍了,如果你对 Spring Boot 还不是很熟悉,或者只是会简单的使用,那还是建议你深入学习下吧,推荐这个 Spring Boot 学习仓库,欢迎 Star 关注:


https://github.com/javastacks/spring-boot-best-practice


1、新建监听器

import lombok.extern.slf4j.Slf4j;
import org.springframework.boot.availability.AvailabilityChangeEvent;
import org.springframework.boot.availability.ReadinessState;
import org.springframework.context.ApplicationListener;
/**
 * 来源微信公众号:Java技术栈
 */
@Slf4j
public class JavastackListener implements ApplicationListener<AvailabilityChangeEvent> {
    @Override
    public void onApplicationEvent(AvailabilityChangeEvent event) {
        log.info("监听到事件:" + event);
        if (ReadinessState.ACCEPTING_TRAFFIC == event.getState()){
            log.info("应用启动完成,可以请求了……");
        }
    }
}

新建一个自定义监听器,实现了 ApplicationListener 接口,泛型 AvailabilityChangeEvent 表示仅仅监听 AvailabilityChangeEvent 事件。


因第 8 步的事件和第 6 步的事件同名,我们可以根据事件的状态来区分到底是哪一个环节的事件 。


2、注册监听器

注册监听器有两种方式:


1、在资源目录中的 META-INF/spring.factories 文件中自动注册:

org.springframework.context.ApplicationListener=\
cn.javastack.springboot.features.listener.JavastackListener

2、如果是监听 Spring 应用上下文(ApplicationContext)创建之后的事件,可以直接在监听器上使用 @Component 注解即可,否则需要使用第一种方法的自动注册,因为 ApplicationContext 并未创建,这时的 Bean 是不能被加载的。


3、应用启动

下面来看下启动日志:

image.png



可以看到同时输出了第 6 步和 8 步的监听日志,但只输出第 8 步的启动完成日志,自定义监听实现成功。


总结

了解了 Spring Boot 启动过程中的各个事件及监听机制,大家可以依葫芦画瓢实现 Spring Boot 启动过程中的各个自定义操作,比如说在启动过程上实现动态注册、移除 Bean 等。


一般来说,不建议使用事件和监听器来实现比较耗时和繁重的任务,这样会影响应用程序的正常启动,考虑使用 Spring Boot 的 application/ command-line runners 来进行实现。


本文只是介绍了一下 Spring Boot 启动过程中的事件及如何实现自定义监听器,怎么实现一个业务上的自定义事件和监听器不在本文范围之类,后续栈长再开一篇,关注公众号Java技术栈第一时间推送,不要走开。


本文实践所有源代码已上传:


https://github.com/javastacks/spring-boot-best-practice


参考资料:


https://docs.spring.io/spring-boot/docs/2.3.5.RELEASE/reference/htmlsingle/#boot-features-application-events-and-listeners


相关文章
|
22天前
|
存储 安全 Java
事件的力量:探索Spring框架中的事件处理机制
事件的力量:探索Spring框架中的事件处理机制
33 0
|
22天前
|
Java 应用服务中间件 Maven
SpringBoot 项目瘦身指南
SpringBoot 项目瘦身指南
72 0
|
22天前
|
安全 Java Spring
SpringBoot2 | SpringBoot监听器源码分析 | 自定义ApplicationListener(六)
SpringBoot2 | SpringBoot监听器源码分析 | 自定义ApplicationListener(六)
56 0
|
22天前
|
XML Java 数据格式
聊聊Spring事件及其应用
在 JDK 中已经提供相应的自定义事件发布功能的基础类: - `java.util.EventObject`类 :自定义**事件**类型 - `java.util.EventListener`接口:事件的**监听器**
41 1
聊聊Spring事件及其应用
|
22天前
|
Java 容器
SpringBoot3 事件和监听器
SpringBoot3 事件和监听器
|
22天前
|
安全 Java 应用服务中间件
江帅帅:Spring Boot 底层级探索系列 03 - 简单配置
江帅帅:Spring Boot 底层级探索系列 03 - 简单配置
35 0
江帅帅:Spring Boot 底层级探索系列 03 - 简单配置
|
22天前
|
XML Java C++
【Spring系列】Sping VS Sping Boot区别与联系
【4月更文挑战第2天】Spring系列第一课:Spring Boot 能力介绍及简单实践
42 0
【Spring系列】Sping VS Sping Boot区别与联系
|
22天前
|
Java Spring
flowable 监听器无法获取spring bean ,自动注入bean为null,解决方案
flowable 监听器无法获取spring bean ,自动注入bean为null,解决方案
|
22天前
|
Java Spring
除了spring自带的事件,你还可以这样使用事件
除了spring自带的事件,你还可以这样使用事件
18 3
|
22天前
|
存储 安全 Java
全面探索Spring框架中的事件处理机制
在现代应用程序中,各个组件之间的通信是至关重要的。想象一下,你的应用程序中的各个模块像是一个巨大的交响乐团,每个模块都是一位音乐家,而Spring事件机制就像是指挥家,将所有音乐家协调得天衣无缝。这种松耦合的通信方式使你的应用程序更加灵活、可维护,而且能够轻松应对变化。现在,让我们进入这个令人兴奋的音乐厅,探索Spring事件的世界。