Spring 事件处理怎么用?Spring 事件监听和发布机制详解

文章导读
Previous Quiz Next 在所有章节中你已经看到,Spring 的核心是 ApplicationContext,它管理 bean 的完整生命周期。ApplicationContext 在加载 bean 时会发布某些类型的事件。例如,当 context 启动时会发布
📋 目录
  1. A 标准事件
  2. B 监听 Context 事件
A A

Spring 中的事件处理



Previous
Quiz
Next

在所有章节中你已经看到,Spring 的核心是 ApplicationContext,它管理 bean 的完整生命周期。ApplicationContext 在加载 bean 时会发布某些类型的事件。例如,当 context 启动时会发布 ContextStartedEvent,当 context 停止时会发布 ContextStoppedEvent

ApplicationContext 中的事件处理通过 ApplicationEvent class 和 ApplicationListener interface 提供。因此,如果一个 bean 实现了 ApplicationListener,那么每次向 ApplicationContext 发布 ApplicationEvent 时,该 bean 都会收到通知。

标准事件

Spring 提供了以下标准事件 −

序号 Spring 内置事件及描述
1

ContextRefreshedEvent

ApplicationContext 初始化或刷新时发布此事件。这也可以通过 ConfigurableApplicationContext interface 的 refresh() 方法来触发。

2

ContextStartedEvent

当使用 ConfigurableApplicationContext interface 的 start() 方法启动 ApplicationContext 时发布此事件。收到此事件后,你可以轮询数据库或重启任何已停止的应用。

3

ContextStoppedEvent

当使用 ConfigurableApplicationContext interface 的 stop() 方法停止 ApplicationContext 时发布此事件。收到此事件后,你可以执行必要的清理工作。

4

ContextClosedEvent

当使用 ConfigurableApplicationContext interface 的 close() 方法关闭 ApplicationContext 时发布此事件。已关闭的 context 到达生命周期终点;它无法被刷新或重启。

5

RequestHandledEvent

这是一个 Web 特定事件,通知所有 bean 一个 HTTP 请求已被处理。

Spring 的事件处理是单线程的,因此如果发布了一个事件,在所有接收者收到消息之前,进程会被阻塞,流程不会继续。因此,在设计应用时如果使用事件处理,需要特别注意。

监听 Context 事件

要监听 context 事件,bean 应实现 ApplicationListener 接口,该接口只有一个方法 onApplicationEvent()。因此,让我们编写一个示例,来查看事件如何传播,以及如何在特定事件基础上放置代码来执行所需任务。

让我们准备好一个可用的 Eclipse IDE,并按照以下步骤创建一个 Spring 应用程序 −

步骤 描述
1 创建一个名为 spring 的 Maven 项目,groupid 为 com.,artifactid 为 spring,并在创建的项目中的 src 文件夹下创建一个包 com.
2 按照 Spring - 环境设置章节的说明更新 pom.xml。
3 com. 包下创建 Java 类 HelloWorldStartEventHandlerStopEventHandlerMainApp
4 src/main/resources 文件夹下创建 Beans 配置文件 Beans.xml
5 最后一步是为所有 Java 文件和 Bean 配置文件创建内容。最后,按照以下说明运行应用程序。

HelloWorld.java

package com.;

public class HelloWorld {
   private String message;

   public void setMessage(String message){
      this.message  = message;
   }
   public void getMessage(){
      System.out.println("Your Message : " + message);
   }
}

StartEventHandler.java

package com.;

import org.springframework.context.ApplicationListener;
import org.springframework.context.event.ContextStartedEvent;

public class StartEventHandler 
   implements ApplicationListener<ContextStartedEvent>{

   public void onApplicationEvent(ContextStartedEvent event) {
      System.out.println("ContextStartedEvent Received");
   }
}

StopEventHandler.java

package com.;

import org.springframework.context.ApplicationListener;
import org.springframework.context.event.ContextStoppedEvent;

public class StopEventHandler 
   implements ApplicationListener<ContextStoppedEvent>{

   public void onApplicationEvent(ContextStoppedEvent event) {
      System.out.println("ContextStoppedEvent Received");
   }
}

MainApp.java

package com.;

import org.springframework.context.ConfigurableApplicationContext;
import org.springframework.context.support.ClassPathXmlApplicationContext;

public class MainApp {
   public static void main(String[] args) {
      ConfigurableApplicationContext context = 
         new ClassPathXmlApplicationContext("Beans.xml");

      // 触发启动事件。
      context.start();
	  
      HelloWorld obj = (HelloWorld) context.getBean("helloWorld");
      obj.getMessage();

      // 触发停止事件。
      context.stop();
   }
}

Beans.xml

<?xml version = "1.0" encoding = "UTF-8"?>

<beans xmlns = "http://www.springframework.org/schema/beans"
   xmlns:xsi = "http://www.w3.org/2001/XMLSchema-instance"
   xsi:schemaLocation = "http://www.springframework.org/schema/beans
   http://www.springframework.org/schema/beans/spring-beans-3.0.xsd">

   <bean id = "helloWorld" class = "com..HelloWorld">
      <property name = "message" value = "Hello World!"/>
   </bean>

   <bean id = "cStartEventHandler" class = "com..StartEventHandler"/>
   <bean id = "cStopEventHandler" class = "com..StopEventHandler"/>

</beans>

输出

完成源代码和 bean 配置文件创建后,让我们运行应用程序。如果应用程序一切正常,它将打印以下消息 −

ContextStartedEvent Received
Your Message : Hello World!
ContextStoppedEvent Received

如果您愿意,可以发布自己的自定义事件,然后捕获这些事件以针对这些自定义事件采取行动。如果您对编写自己的自定义事件感兴趣,可以查看 Spring 中的 Custom Events。