ApplicationContext的事件机制简介
1,事件源:ApplicationContext.publishEvent()方法:用于主动触发容器事件。
2,事件:ApplicationEvent类,容器事件,必须由ApplicationContext发布。(实际应用时,容器事件除了
继承了ApplicationEvent类外,其实它就是一个普通的Java类)
3,事件监听器:ApplicationListener接口,可由容器中任何监听器Bean担任。onApplicationEvent(ApplicationEvent event):
用于对事件的处理,每当容器内发生任何事件时,此方法都被触发。
这三者是什么关系?
ApplicationContext 通过publishEvent方法(该方法继承于接口ApplicationEventPublisher)发布事件(ApplicaitonEvent), 然后由ApplicationListener监听处理。
实际上,Spring的事件机制与所有时间机制都基本相似,它们都需要事件源、事件和事件监听器组成。
只是此处的事件源是ApplicationContext,且事件必须由Java程序显式触发。下面的程序将演示Spring容器的事件机制。
事件机制一个例子
1,先定义了一个ApplicationEvent类,其对象就是一个Spring容器事件,代码如下:
public class EmailEvent extends ApplicationEvent{
private String address;
private String text;
public EmailEvent(Object source, String address, String text){
super(source);
this.address = address;
this.text = text;
}
public EmailEvent(Object source) {
super(source);
}
//......address和text的setter、getter
}
上面的EmailEvent类继承了ApplicationEvent类,除此之外,它就是一个普通的Java类。
2,容器监听器类代码如下:
public class EmailNotifier implements ApplicationListener {
@Override
public void onApplicationEvent(ApplicationEvent applicationEvent) {
if (applicationEvent instanceof EmailEvent){
EmailEvent emailEvent = (EmailEvent) applicationEvent;
System.out.println("需要发送邮件的接收地址: " + emailEvent.getAddress());
System.out.println("需要发送邮件的邮件正文: " + emailEvent.getText());
}else {
System.out.println("容器本身的事件: " + applicationEvent);
}
}
}
容器事件的监听器类必须实现 ApplicationListener 接口,并复写 onApplicationEvent() 方法
- onApplicationEvent(ApplicationEvent event):每当容器内发生任何事件时,此方法都会被触发
3,将监听器配置在Spring的容器中,代码如下:
<bean class="org.spring.listener.EmailNotifier"/>
为Spring容器注册监听器,不需要像AWT编程那样采用代码进行注册,只需要在Spring的配置文件中进行简单配置即可。当我们在Spring中配置了一个实现了ApplicationListener的Bean,Spring容器就会把这个Bean当成容器事件的监听器。
4,主动触发容器事件,代码如下:
public class SpringTest {
public static void main(String[] args){
ApplicationContext ctx = new ClassPathXmlApplicationContext("spring-config.xml");
//创建一个ApplicationEvent对象
//EmailEvent ele = new EmailEvent("hello","spring_test@163.com","this is a test");
//主动触发该事件
//ctx.publishEvent(ele);
}
}
当系统创建Spring容器、加载Spring容器时会自动触发容器事件,容器事件监听器可以监听到这些事件。除此之外,程序也可以调用 ApplicationContext 的 publishEvent()方法 来主动触发一个容器事件
5,程序到此结束,运行结果如下:
容器本身的事件: org.springframework.context.
event
.ContextRefreshedEvent[source=org.springframework.context.support.ClassPathXmlApplicationContext@b81eda8: startup date [Thu Dec 04 20:20:52 CST 2014]; root of context hierarchy]
6,若取消main中的注释,即,使用publishEvent()来触发事件,运行结果如下:
容器本身的事件: org.springframework.context.
event
.ContextRefreshedEvent[source=org.springframework.context.support.ClassPathXmlApplicationContext@b81eda8: startup date [Thu Dec 04 20:24:03 CST 2014]; root of context hierarchy]
需要发送邮件的接收地址: spring_test@163.com
需要发送邮件的邮件正文:
this
is
a test
注意:如果Bean想发布事件,则Bean必须获得其容器的引用。如果程序中没有直接获取容器的引用,则应该让Bean实现ApplicationContextAware或者BeanFactoryAware接口,从而可以获得容器的引用。
详细介绍
ApplicationContext事件机制是观察者设计模式的实现,通过ApplicationEvent类和ApplicationListener接口,可以实现ApplicationContext事件处理。
ApplicationListener Bean,每当ApplicationContext发布ApplicationEvent时,ApplicationListener Bean将自动被触发。
Spring的事件框架有如下两个重要的成员:
- ApplicationEvent:容器事件,必须由ApplicationContext发布
- ApplicationListener:监听器,可由容器中的任何监听器Bean担任
扩展了解:Spring提供如下几个内置事件:
- ContextRefreshedEvent:ApplicationContext容器初始化或刷新时触发该事件。此处的初始化是指:所有的Bean被成功装载,后处理Bean被检测并激活,所有Singleton Bean 被预实例化,ApplicationContext容器已就绪可用
- ContextStartedEvent:当使用ConfigurableApplicationContext(ApplicationContext的子接口)接口的start()方法启动ApplicationContext容器时触发该事件。容器管理声明周期的Bean实例将获得一个指定的启动信号,这在经常需要停止后重新启动的场合比较常见(https://www.cnblogs.com/weilunhui/p/4143793.html)
- ContextClosedEvent:当使用ConfigurableApplicationContext接口的close()方法关闭ApplicationContext时触发该事件
- ContextStoppedEvent:当使用ConfigurableApplicationContext接口的stop()方法使ApplicationContext容器停止时触发该事件。此处的停止,意味着容器管理生命周期的Bean实例将获得一个指定的停止信号,被停止的Spring容器可再次调用start()方法重新启动
- RequestHandledEvent:Web相关事件,只能应用于使用DispatcherServlet的Web应用。在使用Spring作为前端的MVC控制器时,当Spring处理用户请求结束后,系统会自动触发该事件。
参考来源:
https://www.cnblogs.com/weilunhui/p/4143793.html