从前面的内容我们知道Spring核心时ApplicationContext
,管理了beans的整个生命周期。ApplicationContext
在加载beans的时候会产生某些类型的事件。例如:当context开始的时候会产生ContextStartedEvent
的事件,当context结束的适合会产生ContextStoppedEvent
事件。
ApplicationContext
中的事件处理由ApplicationEvent
类和ApplicationListener
接口提供的。因此,如果一个bean实现了ApplicationListener
接口,然后任意时间ApplicationContext
产生一个ApplicationEvent
时,那个bean就会收到通知。
Spring 提供以下标准事件:
No | Spring Build-in Events | Description |
---|---|---|
1 | ContextRefreshedEvent | 当ApplicationContext 初始化或者被刷新的时候回产生该事件,使用ConfigurableApplictionContext 接口的refresh() 方法也会产生该事件 |
2 | ContextStartedEvent | 当ApplicationContext 使用ConfigurableApplicationContext 接口的start() 方法时会产生该事件。你可以轮询数据库,或者在受到该事件的适合重启已停止的应用程序 |
3 | ContextStoopedEvent | 当ApplicationContext 使用ConfigurableApplicationContext 接口的stop() 方法时会产生该事件。收到这个事件的时候,你可以做一些必要的工作(You can do required housekeep work after receiving this event.) |
4 | ContextClosedEvent | 当ApplicationContext 使用ConfigurableApplicationContext 接口的close() 方法时会产生该事件。一个关闭的context会产生该事件,它不能被刷新和重启。 |
5 | RequestHandledEvent | 这是一个web事件,通知所有的beans一个Http请求已经到了。 |
Spring的事件处理是单线程的,直到一个事件被处理完成,否则进程会被阻塞。因此,当你设计一个包含事件处理的应用程序时要小心。
Listening to Context Events
为了监听一个context事件,bean必须实现ApplicationListener
接口唯一的onApplicationEvent()
方法。因此,让我们编写一个事件了解一个事件如何传播,以及如何完成基于某种事件的任务代码。
HelloWorld.java
package com.soygrow.EventHandler;
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
package com.soygrow.EventHandler;
import org.springframework.context.ApplicationListener;
import org.springframework.context.event.ContextStartedEvent;
public class CStartEventHandler implements ApplicationListener<ContextStartedEvent>{
@Override
public void onApplicationEvent(ContextStartedEvent contextStartedEvent) {
System.out.println("ContextStartedEvent Received!");
}
}
CStopEventHandler.java
package com.soygrow.EventHandler;
import org.springframework.context.ApplicationListener;
import org.springframework.context.event.ContextStoppedEvent;
public class CStopEventHandler implements ApplicationListener<ContextStoppedEvent> {
@Override
public void onApplicationEvent(ContextStoppedEvent contextStoppedEvent) {
System.out.println("ContextStoppedEvent Received!");
}
}
MainApp.java
package com.soygrow.EventHandler;
import org.springframework.context.ConfigurableApplicationContext;
import org.springframework.context.support.ClassPathXmlApplicationContext;
public class MainApp {
public static void main(String[] args) {
ConfigurableApplicationContext context =
new ClassPathXmlApplicationContext("EventBeans.xml");
context.start();
HelloWorld helloWorld = (HelloWorld) context.getBean("helloWorld");
helloWorld.getMessage();
context.stop();
}
}
如果一切正常,那么运行的结果是:
ContextStartedEvent Received!
Your Message : Hello World!!!
ContextStoppedEvent Received!
代码分析:
- ApplicationListener 包含文章开始的五个事件,当然还有其他事件
- onApplicationEvent 是接口的唯一方法
- 另外上文说了,事件处理的流程是单线程的,我试了在CStartEventHandler
中添加下面代码,所有的一切都在等待
try {
Thread.sleep(3000);
} catch (InterruptedException e) {
e.printStackTrace();
}