ApplicationContext的事件机制是观察者设计模式的实现,通过ApplicationEvent类和ApplicationListener接口,可以实现ApplicationContext的事件处理。如果容器中有一个ApplicationListener Bean,每当ApplicationContext发布 ApplicationEvent时,ApplicationListenerBean就会自动触发。
Spring的事件框架有如下两个重要成员:
ApplicationEvent:容器事件,必须由ApplicationContext发布。
ApplicationListener:监听器,可由容器中的任何监听器Bean担任。
Spring的事件机制需要事件源、事件和事件监听器组成。只是此处的事件是ApplicationContext,且事件必须由java程序显示触发。下图简单示范了ApplicationContext的事件流程。
下面实例展示了Spring容器的事件机制。
1)、定义一个ApplicationEvent类,其对象就是Spring容器事件。
1. <span style="font-family:Arial;">public class EmailEvent extends ApplicationEvent {
2. private static final long serialVersionUID = 1L;
3.
4. private String address;
5. private String text;
6.
7. // 定义一个带参的构造函数
8. public EmailEvent(Object source) {
9. super(source);
10. }
11.
12. public EmailEvent(Object source, String address, String text) {
13. super(source);
14. this.address = address;
15. this.text = text;
16. }
17.
18. public String getAddress() {
19. return address;
20. }
21.
22. public void setAddress(String address) {
23. this.address = address;
24. }
25.
26. public String getText() {
27. return text;
28. }
29.
30. public void setText(String text) {
31. this.text = text;
32. }
33.
34. }</span>
容器事件的监听器类必须实现ApplicationListener接口,它的实现方法如下:
onAPplicationEvent(ApplicationEventevent):每当容器内发生任何事件时,此方法都会被触发。
2)、编写该容器的监听器类。
1. public class EmailNotifier implements ApplicationListener{
2.
3. //该方法会在容器发生事件时触发
4. public void onApplicationEvent(ApplicationEvent event) {
5. if(event instanceof EmailEvent){
6. //只处理EmailEvent,发送email通知
7. EmailEvent emailEvent = (EmailEvent) event;
8. "需要发送邮件的接收地址为:"+emailEvent.getAddress());
9.
10. "需要发送邮件的邮件正文是:"+emailEvent.getText());
11. }
12. else {
13. //容器内置事件不作任何处理
14. "容器本身的事件:"+event);
15. }
16. }
17.
18. }
3)、将监听器类配置在容器中。
在为Spring容器注册监听器时,我们只需在Spring配置文件中配置一个实现了ApplicationListener的Bean即可,Spring容器会把这个Bean当做容器事件的监听器。
1. <?xml version="1.0" encoding="UTF-8"?>
2. <beans xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
3. xmlns="http://www.springframework.org/schema/beans"
4. xsi:schemaLocation="http://www.springframework.org/schema/beans
5. >
6.
7. <!-- 配置监听器 -->
8. <bean class="com.app.listener.EmailNotifier"/>
9.
10. </beans>
通过上面的3个步骤就可以实现Spring容器的事件了。当系统创建Spring容器,加载Spring容器时会自动触发容器事件,容器事件监听器可以监听到这些事件。同时我们也可以调用ApplicationContext的pulishEvent()方法来主动触发容器事件。
1. public class SpringTest {
2.
3. public static void main(String[] args) {
4. new ClassPathXmlApplicationContext("bean.xml");
5. //创建一个ApplicationEvent对象
6. new EmailEvent("hell","spring_test@163.com","this is a test");
7.
8. //主动触发容器事件
9. ctx.publishEvent(emailEvent);
10. }
11.
12. }
如果Bean想发布事件,则Bean必须获得其容器的引用。如果程序中没有直接获取容器的引用,则应该让Bean实现ApplicationContextAware或BeanFactoryAware接口,从而获得容器的引用。
除了我们可以自己实现Spring容器的事件外,Spring也提供了几个内置事件:
1、 ContextRefreshedEvent:ApplicationContext容器初始化或者刷新时触发该事件。
2、 ContextStartedEvent:当使用ConfigurableApplicationContext接口的start()方法启动ApplicationContext容器时触发该事件。
3、 ContextClosedEvent:当使用ConfigurableApplicationContext接口的close()方法关闭ApplicationContext容器时触发该事件。
4、 ContextStopedEvent: 当使用ConfigurableApplicationContext接口的stop()方法停止ApplicationContext容器时触发该事件。