欢迎进入《一起学spring》系列博文第三篇,
spring容器的事件监听机制,同样有事件、事件源和监听者。而spring中的事件需要继承ApplicationEvent,监听者需要继承ApplicationListener。其他的基本和普通的事件监听差不多。我们用示例说话!
1、这是spring的ApplicationEvent类的源码,我们可以看到它继承了JDK中的EventObject,EventObject中只有一个Object类型的source属性以及一个getSource方法。下面这个ApplicationEvent类只是增加了一个时间戳的属性以及getTimeStamp的方法。
[java] view plain copy
- package org.springframework.context;
- import java.util.EventObject;
- /**
- * Class to be extended by all application events. Abstract as it
- * doesn't make sense for generic events to be published directly.
- *
- * @author Rod Johnson
- * @author Juergen Hoeller
- */
- public abstract class ApplicationEvent extends EventObject {
- /** use serialVersionUID from Spring 1.2 for interoperability */
- private static final long serialVersionUID = 7099057708183571937L;
- /** System time when the event happened */
- private final long timestamp;
- /**
- * Create a new ApplicationEvent.
- * @param source the component that published the event (never {@code null})
- */
- public ApplicationEvent(Object source) {
- super(source);
- this.timestamp = System.currentTimeMillis();
- }
- /**
- * Return the system time in milliseconds when the event happened.
- */
- public final long getTimestamp() {
- return this.timestamp;
- }
- }
2、spring中的ApplicationListener源码;我们可以清楚地知道,这个类和我们自定义监听器中的监听器类基本一样。
[java] view plain copy
- public interface ApplicationListener<E extends ApplicationEvent> extends EventListener {
- /**
- * Handle an application event.
- * @param event the event to respond to
- */
- void onApplicationEvent(E event);
- }
下面回到我们的代码:
3、我的事件
[java] view plain copy
- package com.huai.listener;
- import org.springframework.context.ApplicationEvent;
- public class MyEvent extends ApplicationEvent{
- private String text;
- public MyEvent(Object source) {
- super(source);
- }
- public void setText(String text){
- this.text = text;
- }
- public String getText(){
- return this.text;
- }
- }
4、我的监听器
[java] view plain copy
- package com.huai.listener;
- import org.springframework.context.ApplicationEvent;
- import org.springframework.context.ApplicationListener;
- public class MyListener implements ApplicationListener<ApplicationEvent>{
- @Override
- public void onApplicationEvent(ApplicationEvent event) {
- if(event instanceof MyEvent){
- System.out.println("my event laungh");
- }else{
- System.out.println("other envet");
- }
- }
- }
5、测试类:
[java] view plain copy
- package com.huai.listener;
- import org.springframework.context.support.ClassPathXmlApplicationContext;
- import org.springframework.context.*;
- public class SpringTest {
- public static void main(String[] args) {
- ApplicationContext context = new ClassPathXmlApplicationContext("applicationContext.xml");
- MyEvent event = new MyEvent("hello World");
- event.setText("hello");
- context.publishEvent(event);
- }
- }
仔细看上面的测试类,MyEvent类已经实例化,但MyListener类呢?我们并没有实例化,那么我们应该让容器实例化,所以我们需要在spring的配置文件中告诉spring容器,让它帮我们实例化MyListener类。我们还应该注意到这条代码:context.publishEvent(event);作用是让spring容器中的所有监听器都知道有这样一个事件发生了。在spring源码中的解释是:Notify all listeners registered with this application of an application event. Events may be framework events (such as RequestHandledEvent) or application-specific events.
6、spring的配置文件:我们在spring中配置了一个实现了ApplicationListener的Bean,Spring容器就会把这个bean当成容器事件的监听器。
[java] view plain copy
- <?xml version="1.0" encoding="UTF-8"?>
- <beans xmlns="http://www.springframework.org/schema/beans"
- xmlns:mvc="http://www.springframework.org/schema/mvc" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
- xmlns:context="http://www.springframework.org/schema/context"
- xmlns:aop="http://www.springframework.org/schema/aop" xmlns:tx="http://www.springframework.org/schema/tx"
- xsi:schemaLocation="http://www.springframework.org/schema/beans
- http://www.springframework.org/schema/beans/spring-beans-3.0.xsd
- http://www.springframework.org/schema/context
- http://www.springframework.org/schema/context/spring-context-3.0.xsd
- http://www.springframework.org/schema/aop
- http://www.springframework.org/schema/aop/spring-aop-3.0.xsd
- http://www.springframework.org/schema/tx
- http://www.springframework.org/schema/tx/spring-tx-3.0.xsd
- http://www.springframework.org/schema/mvc
- http://www.springframework.org/schema/mvc/spring-mvc-3.0.xsd">
- <bean class="com.huai.listener.MyListener"/>
- </beans>
运行结果为:
other envet
my event laungh
第一个是spring容器内置的事件;
第二个是我们自己的事件。
实际上,如果开发者需要在spring容器中初始化、销毁时回调自定义的方法,就可以通过上面的事件监听器来实现。