大家都知道,在 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、应用启动

下面来看下启动日志:

可以看到同时输出了第 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

最后,觉得有收获,在看、转发一下哦,原创不易,需要鼓励。

版权申明:本文系公众号 "Java技术栈" 原创,原创实属不易,转载、引用本文内容请注明出处,禁止抄袭、洗稿,请自重,尊重他人劳动成果和知识产权。

近期热文推荐:

1.Java 15 正式发布, 14 个新特性,刷新你的认知!!

2.终于靠开源项目弄到 IntelliJ IDEA 激活码了,真香!

3.我用 Java 8 写了一段逻辑,同事直呼看不懂,你试试看。。

4.吊打 Tomcat ,Undertow 性能很炸!!

5.《Java开发手册(嵩山版)》最新发布,速速下载!

觉得不错,别忘了随手点赞+转发哦!

Spring Boot 启动事件和监听器,太强大了!的更多相关文章

  1. Spring Boot Application 事件和监听器

    https://www.cnblogs.com/fdzfd/p/7872909.html ***************************************************** 一 ...

  2. [Spring Boot] Spring Boot启动过程源码分析

    关于Spring Boot,已经有很多介绍其如何使用的文章了,本文从源代码(基于Spring-boot 1.5.6)的角度来看看Spring Boot的启动过程到底是怎么样的,为何以往纷繁复杂的配置到 ...

  3. Spring Boot启动过程源码分析--转

    https://blog.csdn.net/dm_vincent/article/details/76735888 关于Spring Boot,已经有很多介绍其如何使用的文章了,本文从源代码(基于Sp ...

  4. Spring Boot启动过程(四):Spring Boot内嵌Tomcat启动

    之前在Spring Boot启动过程(二)提到过createEmbeddedServletContainer创建了内嵌的Servlet容器,我用的是默认的Tomcat. private void cr ...

  5. Spring Boot启动过程(七):Connector初始化

    Connector实例的创建已经在Spring Boot启动过程(四):Spring Boot内嵌Tomcat启动中提到了: Connector是LifecycleMBeanBase的子类,先是设置L ...

  6. Spring Boot 启动(二) Environment 加载

    Spring Boot 启动(二) Environment 加载 Spring 系列目录(https://www.cnblogs.com/binarylei/p/10198698.html) 上一节中 ...

  7. Spring Boot 启动(一) SpringApplication 分析

    Spring Boot 启动(一) SpringApplication 分析 Spring 系列目录(https://www.cnblogs.com/binarylei/p/10198698.html ...

  8. Spring Boot实践——事件监听

    借鉴:https://blog.csdn.net/Harry_ZH_Wang/article/details/79691994 https://blog.csdn.net/ignorewho/arti ...

  9. Spring Boot启动流程分析

    引言 早在15年的时候就开始用spring boot进行开发了,然而一直就只是用用,并没有深入去了解spring boot是以什么原理怎样工作的,说来也惭愧.今天让我们从spring boot启动开始 ...

随机推荐

  1. JVM(一)-JVM入门

    JVM的定义: JVM是Java Virtual Machine(Java虚拟机)的缩写,JVM是一种用于计算设备的规范,它是一个虚构出来的计算机,是通过在实际的计算机上仿真模拟各种计算机功能来实现的 ...

  2. laravel 验证器使用

    1.前后端不分离 (form表单提交) 控制器定义验证规则 <?php namespace App\Http\Controllers\Admin; use Illuminate\Http\Req ...

  3. Linux学习 - 02 使用 - Centos8 - 『更换rpm/epel包源为国内源』

    1. Centos8 - 『更换rpm/epel包源为国内源』 centos 8 默认是会读取centos.org的mirrorlist的,所以一般来说是不需要配置镜像的. 如果你的网络访问mirro ...

  4. Python:利用Entrez库筛选下载PubMed文献摘要

    一个不是学生物的孩子来搞生物,当真是变成了一块废铁啊,但也是让我体会到了一把生物信息的力量. 废话不多说,开整! 任务:快速高效从PubMed上下载满足条件的文献PMID.标题(TI).摘要(AB). ...

  5. pandas 生成html文档,支持可添加多个表

    如何通过pandas生成html格式?如何通过pandas生成html文件文件中包含多个表单Balance_64_data = pd.read_sql(Balance_64_sql,engine)df ...

  6. MathType怎么写分段函数?

    分段函数是数学里面特有的一种函数,它是对于自变量x的不同的取值范围,有着不同的解析式的函数.它的特点就是有一个大括号,然后有至少2个函数解析式,写这样的函数离不开专业的公式编辑器,下面就来学习具体编辑 ...

  7. mac实用软件推荐 mac好用的软件

    终于入手了梦寐以求的苹果电脑,但却发现其操作系统与Windows大相径庭!不会使用怎么办?不用担心,我们可以借助软件的力量.一款实用的Mac软件不仅能够使你的工作效率显著提高,同时它还能帮助你更快地熟 ...

  8. Hadoop优化之数据压缩

    bBHadoop数据压缩 概述 运行hadoop程序时,I/O操作.网络数据传输.shuffle和merge要花大量的时间,尤其是数据规模很大和工作负载密集的情况下,这个时候,使用数据压缩可以提高效率 ...

  9. Spring简介以及配置信息

      Spring框架是一种轻量级的.一站式的企业级开发解决方案 框架(framework):是一组设计思想.规范.API的精心组合,专门用来解决某一层次或领域的问题 轻量级(lightweight): ...

  10. Alpha冲刺-第八次冲刺笔记

    Alpha冲刺-冲刺笔记 这个作业属于哪个课程 https://edu.cnblogs.com/campus/fzzcxy/2018SE2 这个作业要求在哪里 https://edu.cnblogs. ...