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 中的自定义事件。