JDK事件
java通过java.util.EventObject类和java.util.EventListener接口描述事件和监听器
事件源,事件的产生者,任何一个EventObject都必须拥有一个事件源。
事件监听器注册表,保存事件监听器的地方。
事件广播器,把事件通知给事件监听器。
事件源、事件监听器注册表和事件广播这3个角色有时可以由同一个对象承担,如java.swing包中的JButton、JCheckBox等组件,它们分别集以上3个角色于一身。
事件体系是观察者模式的一种具体实现方式
Spring 事件
Spring的ApplicationContext能够发布事件并且允许注册相应的事件监听器
Spring事件类ApplicationEvent
// 继承了JDK的EventObject
public abstract class ApplicationEvent extends EventObject {
// 唯一的构造方法,source指定事件源
public ApplicationEvent(Object source) {
super(source);
this.timestamp = System.currentTimeMillis();
}
}
Spring事件类ApplicationEvent有两个子类ApplicationContextEvent、RequestHandledEvent
// 容器事件类
public abstract class ApplicationContextEvent extends ApplicationEvent {}
// 与web应用相关的事件RequestHandledEvent,当一个Http请求被处理后,产生该事件
public class RequestHandledEvent extends ApplicationEvent {}
ApplicationContextEvent有4个子类ContextClosedEvent、ContextRefreshedEvent、ContextStartedEvent、ContextStoppedEvent,分别表示容器启动、刷新、停止及关闭的事件。
RequestHandledEvent只有定义了DispatcherServlet时才会产生该事件,它的子类ServletRequestHandledEvent代表Servlet请求事件。
spring事件监听器
// 继承了JDK的EventListener接口
// E extends ApplicationEvent是一个泛型
public interface ApplicationListener<E extends ApplicationEvent> extends EventListener {
// 只定义了一个方法
void onApplicationEvent(E event);
}
ApplicationListener有两个子类GenericApplicationListener、SmartApplicationListener
public interface SmartApplicationListener extends ApplicationListener<ApplicationEvent>, Ordered {
/**
* 指定监听器支持哪种类型的容器事件
*/
boolean supportsEventType(Class<? extends ApplicationEvent> eventType); /**
* 指定监听器仅对何种事件源对象做出响应
*/
boolean supportsSourceType(Class<?> sourceType); } public interface GenericApplicationListener extends ApplicationListener<ApplicationEvent>, Ordered {
/**
* 指定监听器对何种事件类型做出响应
*/
boolean supportsEventType(ResolvableType eventType); /**
* 指定监听器对何种事件源做出响应
*/
boolean supportsSourceType(Class<?> sourceType); }
spring事件广播器
public interface ApplicationEventMulticaster {}
ApplicationEventMulticaster有两个子类AbstractApplicationEventMulticaster、SimpleApplicationEventMulticaster
public abstract class AbstractApplicationEventMulticaster
implements ApplicationEventMulticaster, BeanClassLoaderAware, BeanFactoryAware {}
public class SimpleApplicationEventMulticaster extends AbstractApplicationEventMulticaster {}
AbstractApplicationContext
AbstractApplicationContext有一个成员变量applicationEventMulticaster,这个成员变量提供了容器监听器的注册表
AbstractApplicationContext的refresh方法
postProcessBeanFactory(beanFactory);
invokeBeanFactoryPostProcessors(beanFactory);
registerBeanPostProcessors(beanFactory);
initMessageSource();
/*
* 初始化应用上下文事件广播器
* 可以自定义事件广播器,实现ApplicationEventMulticaster即可,
* 如果没有找到自定义的广播器,自动使用SimpleApplicationEventMulticaster作为事件广播器
*/
initApplicationEventMulticaster();
onRefresh();
/*
* 注册事件监听器
* 根据反射机制,从BeanDefinitionRegistry中找出所有实现了ApplicationListener的Bean,
* 并注册
*/
registerListeners();
finishBeanFactoryInitialization(beanFactory);
// 容器启动完成,向容器中的所有监听器发布事件
finishRefresh();
demo
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-core</artifactId>
<version>4.3.16.RELEASE</version>
</dependency>
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-context</artifactId>
<version>4.3.16.RELEASE</version>
</dependency>
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-beans</artifactId>
<version>4.3.16.RELEASE</version>
</dependency>
pom.xml
package test; import org.springframework.context.ApplicationContext;
import org.springframework.context.event.ApplicationContextEvent; /**
* 自定义的邮件发送事件类,继承自ApplicationContextEvent
*/
public class MailSendEvent extends ApplicationContextEvent {
private String to;
// 事件源source是ApplicationContext
public MailSendEvent(ApplicationContext source, String to) {
super(source);
this.to = to;
}
public String getTo() {
return this.to;
}
}
自定义事件类
package test; import org.springframework.context.ApplicationListener;
/**
* 自定义的邮件发送事件监听器,继承自ApplicationListener
*/
public class MailSendListener implements ApplicationListener<MailSendEvent>{
// 接收到事件后的处理逻辑
public void onApplicationEvent(MailSendEvent event) {
MailSendEvent mse = (MailSendEvent) event;
System.out.println("MailSendListener:向" + mse.getTo() + "发送完一封邮件");
}
}
自定义事件监听器
package test; import org.springframework.beans.BeansException;
import org.springframework.context.ApplicationContext;
import org.springframework.context.ApplicationContextAware; public class MailSender implements ApplicationContextAware {
private ApplicationContext ctx ;
// 实现了ApplicationContextAware,在bean的生命周期会自动调用这个方法
public void setApplicationContext(ApplicationContext ctx)
throws BeansException {
this.ctx = ctx; }
public void sendMail(String to){
// 发送邮件
System.out.println("MailSender:模拟发送邮件...");
// 创建事件
MailSendEvent mse = new MailSendEvent(this.ctx,to);
// 发布事件
ctx.publishEvent(mse);
}
}
邮件发送器
<?xml version="1.0" encoding="UTF-8" ?>
<beans xmlns="http://www.springframework.org/schema/beans"
xmlns:c="http://www.springframework.org/schema/c"
xmlns:p="http://www.springframework.org/schema/p"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://www.springframework.org/schema/beans
http://www.springframework.org/schema/beans/spring-beans.xsd"> <bean id="sender" class="test.MailSender"/>
<bean id="sendListener" class="test.MailSendListener"/>
</beans>
my.xml
package test; import org.springframework.context.ApplicationContext;
import org.springframework.context.support.ClassPathXmlApplicationContext; public class Driver {
public static void main(String[] args) {
ApplicationContext ctx = new ClassPathXmlApplicationContext("my.xml");
MailSender mailSender = ctx.getBean(MailSender.class);
mailSender.sendMail("test mail.");
System.out.println("done.");
}
}
Driver