Spring 中的事件处理
在所有章节中你已经看到,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 类 HelloWorld、StartEventHandler、StopEventHandler 和 MainApp。 |
| 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。