java 自动启动监听_Spring Boot 启动事件和监听器,太强大了!

大家都知道,在 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

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 关注:

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 {

@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、应用启动

下面来看下启动日志:

842c754c625080e797356cdfeb7ecf97.png

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

总结

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

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

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

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

参考资料:

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

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

近期热文推荐:

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

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/440506.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

java day_Java_Day7(上)

Java learning_Day7(上)内容常用类枚举类型常用类String 类java.lang.String 类代表不可变的字符序列。String 类的常见构造方法:String(String original)创建一个 String 对象为 original 的拷贝。String(char[] value)用一个字符数组创建一个 String 对象。String…

java关键字 valotile_Java内存模型-jsr133规范介绍,java中volatile关键字的含义

最近在看《深入理解Java虚拟机:JVM高级特性与最佳实践》讲到了线程相关的细节知识,里面讲述了关于java内存模型,也就是jsr 133定义的规范。系统的看了jsr 133规范的前面几个章节的内容,觉得受益匪浅。废话不说,简要的介…

Java重载和重写6_深入理解Java中的重写和重载

深入理解Java中的重写和重载重载(Overloading)和重写(Overriding)是Java中两个比较重要的概念。但是对于新手来说也比较容易混淆。本文通过两个简单的例子说明了他们之间的区别。定义重载简单说,就是函数或者方法有同样的名称,但是参数列表不相同的情形&…

python 协程池gevent.pool_进程池\线程池,协程,gevent

目录1. 进程池与线程池2. 协程3. gevent4. 单线程下实现并发的套接字通信首先写一个基于多线程的套接字服务端:from socket import *from threading import Threaddef comunicate(conn):while True: # 通信循环try:data conn.recv(1024)if len(data) 0: breakconn.send(data.…

java poi 3.13_Java 读取Excl文件 (poi-3.13)

最近做项目遇到了读取Excel数据到数据库做数据的初始化。于是找一个。发现(poi-3.13)可以解决问题。可以解析两种格式(xlsx和xls)以下是实现的步骤1.下载poi3.13包,地址(http://poi.apache.org/download.html#POI-3.13)2.学习APi。接下来是还是demo来说明问题吧&…

【CodeChef - CLIQUED 】Bear and Clique Distances(建图,缩点技巧,思维)

题干: 解题报告: 主要就是在于怎么处理那个前K个点:组成一个团。换句话说,缩成一个点。先直接当成每个点多了k条边来处理,T了。想想也是啊,要是K1e5,那就是1e10条边了。。刚开始尝试了半天缩点&…

【HDU - 5649】DZY Loves Sorting(线段树,区间更新区间查询,思维,01缩数变换,线段树分割)

题干: DZY has a sequence a[1..n]a[1..n]. It is a permutation of integers 1∼n1∼n. Now he wants to perform two types of operations: 0lr0lr: Sort a[l..r]a[l..r] in increasing order. 1lr1lr: Sort a[l..r]a[l..r] in decreasing order. After doin…

php错误403_phpstudy访问文件报错403/Forbidden解决办法

使用phpstudy访问WWW目录下的文件时,浏览器提示Forbidden错误,没有访问权限。我在网上搜索了喝多资料以及本人亲自尝试过后,总结了一下两种方法。方法一:打开phpStudy,点击按键“其他选项菜单”>找到phpStudy配置&g…

【CodeForces - 294B】Shaass and Bookshelf(枚举,贪心,思维,组内贪心组间dp)

题干: Shaass has n books. He wants to make a bookshelf for all his books. He wants the bookshelfs dimensions to be as small as possible. The thickness of the i-th book is ti and its pages width is equal to wi. The thickness of each book is eith…

mac php开发集成环境,MAC OS X下php集成开发环境mamp

之前苦于mac上搭建本地服务器之艰辛,找寻好久都没找到一款类似windows上集成的本地服务器环境,诸如phpstudy,xampp,appserv,虽说xampp也有mac版,但不知为何不是Apache启动不了,这里小编为大家分享了MAC OS X 下php集成…

php获取手机目录,php如何获取手机型号

手机App中判断平台,可以根据$_SERVER[HTTP_USER_AGENT]中的内容来判断浏览器类型或手机平台。(推荐学习:PHP编程从入门到精通)iPhone UA:Mozilla/5.0 (iPhone; U; CPU iPhone OS 4_2_1 like Mac OS X; en-us) AppleWebKit/533.17.9 (KHTML, l…

【CodeForces - 920E】Connected Components? (dsu,补图连通块,STLset+map,bfs 或bitset)

题干: You are given an undirected graph consisting of n vertices and edges. Instead of giving you the edges that exist in the graph, we give you m unordered pairs (x, y) such that there is no edge between x and y, and if some pair of vertices…

【牛客 - 551F】CSL 的神奇序列(推公式,猜结论,母函数)

题干: 链接:https://ac.nowcoder.com/acm/contest/551/F 来源:牛客网 题目描述 CSL 有一个神奇的无穷实数序列,他的每一项满足如下关系: 对于任意的正整数 n ,有 , 并且 。 CSL 很清楚这样的序列是唯…

java什么时候创建进程,Java创建进程

Java创建进程1 进程的概念 11.1 进程的概念 11.2 进程的特征 11.3 进程与线程区别 12 进程的创建 12.1 JAVA进程的创建 12.1.1 ProcessBuilder 22.1.2 Runtime 32.1.3 Process 42.2 实例 52.2.1 创建子进程 52.2.2 进程阻塞问题 72.2.3 在java中执行java程序 111 进程的概念1.1…

【牛客 - 157E】青蛙(floyd最短路,建图)

题干: 链接:https://ac.nowcoder.com/acm/contest/157/E 来源:牛客网 题目描述 有一只可爱的老青蛙,在路的另一端发现了一个黑的东西,想过去一探究竟。于是便开始踏上了旅途 一直这个小路上有很多的隧道&#xff0…

php移动端url,什么是PC和移动端URL路径规范化

什么叫PC和手机端URL途径规范性在网址百度搜索引擎提升的全过程中,会牵涉到途径方位的难题。网址中的同一个网页页面只相匹配一个网站地址。一个规范化和简易的网站地址有利于检索和捕捉客户的记忆力,回绝好几条途径,偏向同一个网页页面&…

matlab的diray在哪,matlab笔记

matlab笔记 目录 P5第一章——matlab 概述与格式 P10eps 浮点相对精度inf 无穷大i 或 j 虚数单位pi 圆周率nan 非数nargin 函数输入变量数目nargout 函数输出变量数目realmax 最大正实数realmin 最小正实数real( ) 实部imag( ) 虚部abs( ) 绝对值angle( ) 复数的相位角**matlab…

【CodeForces - 190E】Counter Attack (补图bfs,卡常,dsu)

题干&#xff1a; 无向图中给定n个顶点&#xff0c;m条不存在的边(除了这m条边&#xff0c;其余都存在)&#xff0c;求图的连通分量&#xff0c;及每个连通分量的大小。 解题报告&#xff1a; https://codeforces.com/blog/entry/4556 AC代码&#xff1a; #include<cstd…

matlab 多径 时变 信道 冲击响应,无线信道—时变冲激响应

图1无线信道的作用可以分成大尺度效应和小尺度效应。大尺度的效应就是改变了信号的平均功率&#xff0c;即B点的功率是A点的1/L。因此可以将图1等效成图2图2其中C点的平均功率等于B点的平均功率。L的数值可根据传播模型确定。影响接收机性能的只是信噪比&#xff0c;因此&#…

matlab中均线交易策略,【每日一策】Matlab量化交易策略之 均线选股策略

策略名称&#xff1a;均线选股策略策略说明&#xff1a;对沪深300全市场扫描买入条件&#xff1a;1 短均线大于长均线2 最近N个交易日短均线大于长均线的次数满足某个阈值3 当前交易日的长均线值处于某个高位出场条件&#xff1a;止损&#xff1a;价格跌破入场价的一定百分比止…