欢迎进入《一起学spring》系列博文第三篇,
spring容器的事件监听机制,同样有事件、事件源和监听者。而spring中的事件需要继承ApplicationEvent,监听者需要继承ApplicationListener。其他的基本和普通的事件监听差不多。我们用示例说话!
1、这是spring的ApplicationEvent类的源码,我们可以看到它继承了JDK中的EventObject,EventObject中只有一个Object类型的source属性以及一个getSource方法。下面这个ApplicationEvent类只是增加了一个时间戳的属性以及getTimeStamp的方法。
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;
}
}
public interface ApplicationListener<E extends ApplicationEvent> extends EventListener {
/**
* Handle an application event.
* @param event the event to respond to
*/
void onApplicationEvent(E event);
}
下面回到我们的代码:
3、我的事件
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、我的监听器
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、测试类:
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当成容器事件的监听器。
<?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容器中初始化、销毁时回调自定义的方法,就可以通过上面的事件监听器来实现。
如果你还没看懂,欢迎留言讨论!