Spring中的事件处理

我们在所有章节中都可以看到,Spring 的核心是 ApplicationContext,它管理 bean 的完整生命周期。 ApplicationContext 在加载 bean 时发布某些类型的事件。 例如,ContextStartedEvent 在上下文启动时发布,ContextStoppedEvent 在上下文停止时发布。

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

Spring 提供了以下标准事件

序号 Spring 内置事件 描述
1 ContextRefreshedEvent 此事件在 ApplicationContext 初始化或刷新时发布。 这也可以使用 ConfigurableApplicationContext 接口上的 refresh() 方法触发。
2 ContextStartedEvent 此事件在使用 ConfigurableApplicationContext 接口上的 start() 方法启动 ApplicationContext 时发布。 可以轮询数据库,也可以在收到此事件后重新启动任何停止的应用程序。
3 ContextStoppedEvent 此事件在使用 ConfigurableApplicationContext 接口上的 stop() 方法停止 ApplicationContext 时发布。 收到此事件后,可以进行所需的清理工作。
4 ContextClosedEvent 此事件在使用 ConfigurableApplicationContext 接口上的 close() 方法关闭 ApplicationContext 时发布。 一个已关闭的上下文到达生命周期末端;它不能被刷新或重启。
5 RequestHandledEvent 这是一个特定于 Web 的事件,告诉所有 bean 一个 HTTP 请求已得到服务。

Spring 的事件处理是单线程的,因此如果发布了一个事件,除非所有接收者都收到消息,否则进程会被阻塞并且流程将不会继续。 因此,如果要使用事件处理,在设计应用程序时应该小心。


监听上下文事件

要监听上下文事件,bean 应该实现 ApplicationListener 接口,该接口只有一个方法 onApplicationEvent()。 所以让我们写一个例子来看看事件是如何传播的,以及如何让我们的代码根据某些事件来完成所需的任务。

在 com.jiyik 包下创建 Java 类 HelloWorld、CStartEventHandler、CStopEventHandler 和 MainApp。

这是 HelloWorld.java 文件的内容

HelloWorld.java

package com.jiyik;

public class HelloWorld {
   private String message;

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

以下是 CStartEventHandler.java 文件的内容

CStartEventHandler.java

package com.jiyik;

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

public class CStartEventHandler 
   implements ApplicationListener<ContextStartedEvent>{

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

以下是 CStopEventHandler.java 文件的内容

CStopEventHandler.java

package com.jiyik;

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

public class CStopEventHandler 
   implements ApplicationListener<ContextStoppedEvent>{

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

以下是 MainApp.java 文件的内容

MainApp.java

package com.jiyik;

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

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.jiyik.HelloWorld">
      <property name = "message" value = "Hello World!"/>
   </bean>

   <bean id = "cStartEventHandler" class = "com.jiyik.CStartEventHandler"/>
   <bean id = "cStopEventHandler" class = "com.jiyik.CStopEventHandler"/>

</beans>

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

ContextStartedEvent Received
Your Message : Hello World!
ContextStoppedEvent Received

我们也可以发布自己的自定义事件,稍后可以捕获这些事件从而针对这些自定义事件采取任何行动。 如果对编写自己的自定义事件感兴趣,可以查看 Spring 中的自定义事件

查看笔记

扫码一下
查看教程更方便