Spring4.x 笔记(11):Ioc 容器高级-容器事件
文章目录
了解 Spring 容器事件体系
Spring 的 ApplicationContext 能够发布事件并且允许注册相应的事件监听器,其拥有一套完善的事件发布和监听机制。其类结构如下
事件类:ApplicationEvent
实现类 | 描述 |
---|---|
ApplicationContextEvent | 容器事件,其有4个子类,分别表示容器启动、刷新、停止、关闭的事件 |
RequestHandledEvent | 与Web相关的事件,当一个Http请求被处理后,产生该事件。 |
PayloadApplicationEvent | 4.x新的事件。如果事件发布一个Object对象而不是 ApplicationEvent对象,会被包装成 PayloadApplicationEvent 对象 |
事件监听器接口 ApplicationListener
ApplicationListener 接口只有一个方法,该方法接收 ApplicationEvent 事件对象,在该方法中编写事件响应处理逻辑。
实现 | 描述 |
---|---|
SmartApplicationListener | spring3.x 新增两个方法,指定监听器支持哪种类型的容器事件对象。supportsEventType(Class<? extends ApplicationEvent> eventType)、boolean supportsSourceType(Class<?> sourceType) |
GenericApplicationListener | spring4.2 新增。增强了对泛型,boolean supportsEventType(ResolvableType eventType); ResolvableType 类是一个简单的泛型操作支持类,通过这个类可以轻易获取泛型的实际类型信息 |
@EventListener | Spring4.2 实现的事件监听注解实现 |
事件广播 ApplicationEventMulticaster
当发生容器事件时,容器主控程序将调用事件广播器将事件通知给事件监听器注册表中的事件监听器,事件监听器进行响应
graph TB
A[AbstractApplicationEventMulticaster]-->B[ApplicationEventMulticaster]
C[SimpleApplicationEventMulticaster]-->A
事件发布 ApplicationEventPublisher
Spring 为事件的发布定义了 ApplicationEventPublisher 接口 ,ApplicationContext 上下文实现了该接口。接入接口 ApplicationEventPublisherAware 也被设计实现 ApplicationEventPublisher 功能
ApplicationContext 事件体系的具体实现
Spring 在 ApplicationContext 接口的抽象实现类 AbstractApplicationContext 中完成了事件体系的搭建。AbstractApplicationContext 有一个 ApplicationEventMulticaster 成员变量,提供容器监听器的注册表。在 AbstractApplicationContext 类的容器启动方法 refresh()
中通过3个步骤搭建事件的基础设施,代码清单如下:
// 初始化应用上下文事件广播器
initApplicationEventMulticaster();
// 注册事件监听
registerListeners();
// 完成刷新并发布容器刷新事件,内部 publishEvent(new ContextRefreshedEvent(this));
finishRefresh();
-
初始化应用上下文事件广播器
默认初始化 SimpleApplicationEventMulticaster 作为事件广播器,自己装配自定义(实现 ApplicationEventMulticaster 接口)的事件广播器 Bean,Spring 会通过反射将其注册成容器的事件广播器 -
注册事件监听
Spring 根据反射机制,从 BeanDefinitionRegistry 中找出所有实现了 ApplicationListener 的 Bean ,将它们注册为容器的事件监听器,实际操作是调用 ApplicationEventMulticaster 的addApplicationListener、addApplicationListenerBean
方法,将其添加到事件广播器提供的事件监听器注册表中 -
完成刷新并发布容器刷新事件
容器启动完成,调用事件发布接口先容器中所有的监听器发布事件,在publishEvent(new ContextRefreshedEvent(this));
方法内部,Spring 委托 SimpleApplicationEventMulticaster 将事件通知给事件监听器multicastEvent
方法
简单示例
- 自定义事件类
public class EventBean extends ApplicationEvent {
private String msg;
public EventBean(Object source, String msg) {
super(source);
this.msg = msg;
}
public String getMsg() {
return msg;
}
public void setMsg(String msg) {
this.msg = msg;
}
}
- 事件监听器,只负责监听 EventBean 事件
public class EventListener implements ApplicationListener<EventBean> {
@Override
public void onApplicationEvent(EventBean event) {
System.out.println("监听到的数据: " + event.getMsg());
}
}
- 事件发布
public class EventPublisher {
@Autowired
ApplicationContext applicationContext;
public void publish(String msg) {
EventBean eventBean = new EventBean(this, msg);
applicationContext.publishEvent(eventBean);
}
}