目录

自定义事件监听

Springboot 启动事件监听


Springboot 事件监听为 Bean 与 Bean 之间的消息通信提供支持:当一个 Bean 做完一件事以后,通知另一个 Bean 知晓并做出相应处理,此时,需要后续 Bean 监听当前 Bean 所发生的事件。

自定义事件监听

在 Springboot 中实现自定义事件监听大致可以分为以下四个步骤:

  • 自定义事件,一般是继承 ApplicationEvent 抽象类;
  • 定义事件监听器,一般是实现 ApplicationListener 接口;
  • 注册监听器;
  • 发布事件。

第一步:自定义事件,一般是继承 ApplicationEvent 抽象类。

import org.springframework.context.ApplicationEvent;/*** 自定义事件,继承 ApplicationEvent* @author pjli*/
public class MyApplicationEvent extends ApplicationEvent {private static final long serialVersionUID = 1L;public MyApplicationEvent(Object source) {super(source);System.out.println("触发 MyApplicationEvent 事件...");}}

第二步:定义事件监听器,一般是实现 ApplicationListener 接口。

import org.springframework.context.ApplicationListener;
import org.springframework.stereotype.Component;/*** 事件监听器,实现 ApplicationListener 接口* @author pjli*/@Component
public class MyApplicationListener implements ApplicationListener<MyApplicationEvent>{@Overridepublic void onApplicationEvent(MyApplicationEvent event) {System.out.println("监听到:"+event.getClass().getName()+"事件...");}}

第三步:注册监听器,有以下五种方式。

方式一:在启动类中,使用 ConfigurableApplicationContext.addApplicationListener() 方法注册。

ConfigurableApplicationContext context = SpringApplication.run(MyApplication.class, args);
// 注册 MyApplicationListener 事件监听器
context.addApplicationListener(new MyApplicationListener());

方式二:使用 @Component 等注解将事件监听器纳入到 Spring 容器中管理。

@Component
public class MyApplicationListener implements ApplicationListener<MyApplicationEvent>{ //内容同上,此处省略 }

方式三:在 Springboot 核心配置文件 application.properties 中增加 context.listener.classes = [ 监听器全类名 ]。

context.listener.classes=com.pengjunlee.listener.MyApplicationListener

该 context.listener.classes 配置项在 DelegatingApplicationListener 类的属性常量中指定。

方式四:使用 @EventListener 注解自动生成并注册事件监听器。

import org.springframework.context.event.EventListener;
import org.springframework.stereotype.Component;@Component
public class MyEventHandler {@EventListenerpublic void listenMyApplicationEvent(MyApplicationEvent event) {System.out.println("监听到:" + event.getClass().getName() + "事件...");}}

方式五:通过在 CLASSPATH/META-INF/spring.factories 中添加 org.springframework.context.ApplicationListener = [ 监听器全类名 ] 配置项进行注册.

# Application Listeners
org.springframework.context.ApplicationListener=com.pengjunlee.listener.MyApplicationListener

第四步:发布事件。

在程序启动类中可以使用 ApplicationContext.publishEvent() 发布事件,完整代码如下。

import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.context.ConfigurableApplicationContext;import com.pengjunlee.listener.MyApplicationEvent;
import com.pengjunlee.listener.MyApplicationListener;@SpringBootApplication
public class MyApplication {public static void main(String[] args) {ConfigurableApplicationContext context = SpringApplication.run(MyApplication.class, args);// 注册 MyApplicationListener 事件监听器context.addApplicationListener(new MyApplicationListener());// 发布 MyApplicationEvent 事件context.publishEvent(new MyApplicationEvent(new Object()));// context.getBean(MyEventHandler.class).publishMyApplicationEvent();context.close();}
}

注意:可以通过以下代码将 ApplicationContext 注入到 Bean 中用来发布事件。

@Autowired
ApplicationContext applicationContext;

Springboot 启动事件监听

除了可以对自定义的事件进行监听,我们还能够监听 Springboot 的启动事件,Springbootg 共定义了以下5 种启动事件类型:

  • ApplicationStartingEvent:应用启动事件,在调用 SpringApplication.run() 方法之前,可以从中获取到 SpringApplication 对象,进行一些启动前设置。
  • ApplicationEnvironmentPreparedEvent:Environment准备完成事件,此时可以从中获取到 Environment 对象并对其中的配置项进行查看或者修改。
  • ApplicationPreparedEvent:ApplicationContext准备完成事件,接下来 Spring 就能够向容器中加载 Bean 了 。
  • ApplicationReadyEvent:应用准备完成事件,预示着应用可以接收和处理请求了。
  • ApplicationFailedEvent:应用启动失败事件,可以从中捕获到启动失败的异常信息进行相应处理,例如:添加虚拟机对应的钩子进行资源的回收与释放。

为了验证各个启动事件发生的前后,编写一个测试类进行测试,测试代码如下。

import org.springframework.boot.Banner;
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.boot.context.event.ApplicationEnvironmentPreparedEvent;
import org.springframework.boot.context.event.ApplicationFailedEvent;
import org.springframework.boot.context.event.ApplicationPreparedEvent;
import org.springframework.boot.context.event.ApplicationReadyEvent;
import org.springframework.boot.context.event.ApplicationStartingEvent;
import org.springframework.context.ApplicationListener;
import org.springframework.context.ConfigurableApplicationContext;
import org.springframework.core.env.ConfigurableEnvironment;/*** Springboot 启动事件测试* @author pjli*/
@SpringBootApplication
public class MySpringBootApplication {public static void main(String[] args) {SpringApplication springApplication = new SpringApplication(MySpringBootApplication.class);// 添加 ApplicationStartingEvent 事件监听器springApplication.addListeners((ApplicationListener<ApplicationStartingEvent>) event -> {System.out.println("触发 ApplicationStartingEvent 事件...");SpringApplication application = event.getSpringApplication();application.setBannerMode(Banner.Mode.OFF);});// 添加 ApplicationEnvironmentPreparedEvent 事件监听器springApplication.addListeners((ApplicationListener<ApplicationEnvironmentPreparedEvent>) event -> {System.out.println("触发 ApplicationEnvironmentPreparedEvent 事件...");ConfigurableEnvironment environment = event.getEnvironment();System.out.println("event.name=" + environment.getProperty("event.name"));});// 添加 ApplicationPreparedEvent 事件监听器springApplication.addListeners((ApplicationListener<ApplicationPreparedEvent>) event -> {System.out.println("触发 ApplicationPreparedEvent 事件...");ConfigurableApplicationContext context = event.getApplicationContext();System.out.println("Application context name:" + context.getDisplayName());});// 添加 ApplicationReadyEvent 事件监听器springApplication.addListeners((ApplicationListener<ApplicationReadyEvent>) event -> {System.out.println("触发 ApplicationReadyEvent 事件...");});// 添加 ApplicationFailedEvent 事件监听器springApplication.addListeners((ApplicationListener<ApplicationFailedEvent>) event -> {System.out.println("触发 ApplicationFailedEvent 事件...");Throwable t = event.getException();System.out.println("启动失败:" + t.getMessage());});ConfigurableApplicationContext context = springApplication.run(args);context.close();}
}

当应用正常启动时,打印内容如下:

触发 ApplicationStartingEvent 事件...
触发 ApplicationEnvironmentPreparedEvent 事件...
event.name=pengjunlee
触发 ApplicationPreparedEvent 事件...
Application context name:org.springframework.boot.context.embedded.AnnotationConfigEmbeddedWebApplicationContext@49e202ad
触发 ApplicationReadyEvent 事件...

当应用重复启动两次,由于端口被占用而启动失败时,打印内容如下:

触发 ApplicationStartingEvent 事件...
触发 ApplicationEnvironmentPreparedEvent 事件...
event.name=pengjunlee
触发 ApplicationPreparedEvent 事件...
Application context name:org.springframework.boot.context.embedded.AnnotationConfigEmbeddedWebApplicationContext@49e202ad
触发 ApplicationFailedEvent 事件...
启动失败:Connector configured to listen on port 8080 failed to start

由此可以看出 Springboot 启动事件的发生顺序是:Starting -->EnvironmentPrepared --> Prepared-->Ready/Failed

本文项目源码已上传至CSDN,资源地址:https://download.csdn.net/download/pengjunlee/10332845

SpringBoot重点详解--事件监听相关推荐

  1. React Native - Keyboard API使用详解(监听处理键盘事件)

    参考: React Native - Keyboard API使用详解(监听处理键盘事件) 当我们点击输入框时,手机的软键盘会自动弹出,以便用户进行输入. 但有时我们想在键盘弹出时对页面布局做个调整, ...

  2. Android Activity 生命周期详解及监听

    前言 系列文章: Android Activity 与View 的互动思考 Android Activity 生命周期详解及监听 Android onSaveInstanceState/onResto ...

  3. oracle监听器配置详解,Oracle 监听配置详解

    客户端不需要知道数据库名字和实例名字,只需要知道数据库对外提供的服务名(service_name)就可以申请连接到数据库.这个服务名字可以设置成和实例名字一样,也可以根据业务需求设计.在数据库启动过程 ...

  4. SpringBoot重点详解--整合hive-jdbc

    目录 添加依赖与配置 配置数据源与JdbcTemplate 使用DataSource操作 Hive 使用 JdbcTemplate 操作 Hive 启动测试 创建Hive表 查看Hive表 导入数据 ...

  5. SpringBoot重点详解--使用Junit进行单元测试

    目录 添加依赖与配置 ApplicationContext测试 Environment测试 MockBean测试 Controller测试 情况一 情况二 方法一 方法二 本文将对在Springboo ...

  6. SpringBoot重点详解--log4j.properties配置详解与实例

    ################################################################################ #①配置根Logger,其语法为: # ...

  7. SpringBoot重点详解--使用过滤器映射访问路径

    目录 添加Maven依赖 配置地址映射 MapsApplication应用启动类 MapsInitializeListener初始化监听器 MapsUtils工具类 MapsFilter过滤器 Map ...

  8. SpringBoot重点详解--dbcp2数据源配置

    目录 DBCP2详细的配置表 常用链接配置 数据源连接数量配置 事务属性配置 数据源连接健康状况检查 缓存语句 连接泄露回收 DBCP2详细的配置表 常用链接配置 参数 描述 username 传递给 ...

  9. SpringBoot重点详解--@JoinColumn注解

    目录 @OneToOne(一对一) @OneToMany(一对多) @ManyToOne(多对一) @ManyToMany(多对多) @JoinColumn 注解的作用:用来指定与所操作实体或实体集合 ...

最新文章

  1. 怎么安装MYSQL5.0的JDBC驱动
  2. Github学习系列之Github是什么?
  3. Page.LoadTemplate的使用
  4. poj 1077 Eight(A*)
  5. 【知识小课堂】mongodb 之 特殊集合及索引
  6. idea创建多模块Springboot项目、导入多模块、删除多模块
  7. java 注解报错_eclipse编译项目:Java @Override 注解报错的解决方法
  8. 【MATLAB】三维曲线(plot3)
  9. Python计算器练习
  10. android仿饿了么筛选,Android仿饿了么搜索功能
  11. 数据抽取oracle_【跟我学】特征抽取算法与应用
  12. Java基础(四):异常处理
  13. Vivado HLS教程
  14. 架构之美 | 按图索骥,就能做好架构图!
  15. 真香!微软办公环境大揭秘!
  16. python Exception happened during processing of request from( 127.0.0.1 xxx) error [10053]
  17. 2020年10月25日总结
  18. Python绘制中国五星红旗及美国星条旗源代码
  19. Jsonp跨域漏洞浅析
  20. Transition(过渡动画效果)

热门文章

  1. uni H5 苹果手机调微信支付失败
  2. Ambari Server重启报错的解决办法
  3. 关于本人树莓派捣鼓过程中的一些记录
  4. 弹出停止U盘安全删除硬件的命令
  5. 使用css样式做出亚克力背景和透明背景
  6. ASP.NET_母版页嵌套母版页
  7. Python3下载安装教程并安装numpy模块
  8. android m4a播放器,如何在android上解码m4a音频
  9. 利用c#快速知道哪些qq好友空间屏蔽了自己
  10. BUPT OJ143 Triangle