Spring的事件驱动模型
事件驱动模型的三大组成部分
-
事件:ApplicationEvent 抽象类—继承自 JDK 的 EventObject
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 {@code ApplicationEvent}.
* @param source the object on which the event initially occurred or with
* which the event is associated (never {@code null})
*/
public ApplicationEvent(Object source) {
super(source);
this.timestamp = System.currentTimeMillis();
}
/**
* Return the system time in milliseconds when the event occurred.
*/
public final long getTimestamp() {
return this.timestamp;
}
}
所有事件将继承于 ApplicationEvent,并通过继承自EventObject 的成员变量 source 获取到事件源 (注册事件监听器和发布事件的地方) ;Spring中 事件源 一般是容器本身。
如:ApplicationContextEvent(也是一个抽象的事件)--容器事件
public abstract class ApplicationContextEvent extends ApplicationEvent {
/**
* Create a new ContextStartedEvent.
* @param source the {@code ApplicationContext} that the event is raised for
* (must not be {@code null})
*/
public ApplicationContextEvent(ApplicationContext source) {
super(source);
}
/**
* Get the {@code ApplicationContext} that the event was raised for.
*/
public final ApplicationContext getApplicationContext() {
return (ApplicationContext) getSource();
}
}
具体容器事件有:
ContextStartedEvent,ContextStopedEvent,ContextClosedEvent,ContextRefreshedEvent
PayloadApplicationEvent—Spring 4.2之后框架提供的 ApplicationEvent 的子类由于是泛型类,所以可以用来包装任何事件;在容器内部发送的任意类型的事件都会被包装成为 PayloadApplicationEvent 事件对象;包括前面介绍的四个具体 容器事件类
public class PayloadApplicationEvent<T> extends ApplicationEvent implements ResolvableTypeProvider {
private final T payload;
/**
* Create a new PayloadApplicationEvent.
* @param source the object on which the event initially occurred (never {@code null})
* @param payload the payload object (never {@code null})
*/
public PayloadApplicationEvent(Object source, T payload) {
super(source);
Assert.notNull(payload, "Payload must not be null");
this.payload = payload;
}
@Override
public ResolvableType getResolvableType() {
return ResolvableType.forClassWithGenerics(getClass(), ResolvableType.forInstance(getPayload()));
}
/**
* Return the payload of the event.
*/
public T getPayload() {
return this.payload;
}
}
事件监听器(ApplicationListener)— 继承自 JDK 的 EventListener
JDK 要求所有的监听器都要继承这个 EventListener
@FunctionalInterface
public interface ApplicationListener<E extends ApplicationEvent> extends EventListener {
/**
* Handle an application event.
* @param event the event to respond to
*/
void onApplicationEvent(E event);
}
Spring 中 定义了 ApplicationListener 的两个自接口:SmartApplicationListener,
//实现 Ordered 接口 支持排序功能 ,对监听器进行排序
public interface SmartApplicationListener extends ApplicationListener<ApplicationEvent>, Ordered {
/**
* Determine whether this listener actually supports the given event type.
* @param eventType the event type (never {@code null})
* 判断事件类型 是否和当前 监听者匹配--基于这个方法 筛选监听者感兴趣的事件
*/
boolean supportsEventType(Class<? extends ApplicationEvent> eventType);
/**
* Determine whether this listener actually supports the given source type.
* <p>The default implementation always returns {@code true}.
* @param sourceType the source type, or {@code null} if no source
* 判断事件源类型 是否和当前 监听者匹配 -- 基于这个方法 筛选监听者感兴趣的事件源
*/
default boolean supportsSourceType(@Nullable Class<?> sourceType) {
return true;
}
/**
* Determine this listener's order in a set of listeners for the same event.
* <p>The default implementation returns {@link #LOWEST_PRECEDENCE}.
*/
@Override
default int getOrder() {
return LOWEST_PRECEDENCE;
}
}
public interface GenericApplicationListener extends ApplicationListener<ApplicationEvent>, Ordered {
/**
* Determine whether this listener actually supports the given event type.
* @param eventType the event type (never {@code null})
* 判断事件类型 是否和当前 监听者匹配--基于这个方法 筛选监听者感兴趣的事件
* 事件类型 ResolvableType
* 是Spring 4 之后添加的 获取泛型信息的工具,通过这个工具类可以获取到传入的 泛型的各种信息
*/
boolean supportsEventType(ResolvableType eventType);
/**
* Determine whether this listener actually supports the given source type.
* <p>The default implementation always returns {@code true}.
* @param sourceType the source type, or {@code null} if no source
* 判断事件源类型 是否和当前 监听者匹配 -- 基于这个方法 筛选监听者感兴趣的事件源
*/
default boolean supportsSourceType(@Nullable Class<?> sourceType) {
return true;
}
/**
* Determine this listener's order in a set of listeners for the same event.
* <p>The default implementation returns {@link #LOWEST_PRECEDENCE}.
*/
@Override
default int getOrder() {
return LOWEST_PRECEDENCE;
}
}
- 用户可以实现 ApplicationListener 接口 实现方法 onApplicationEvent 来自定义自己的 事件监听器 。也可以使用注解@EventListener 在想 成为监听器的 Bean 监听方法上加上该注解
-
事件发布器(ApplicationEventPublisher和 ApplicationEventMulticaster)容器接口继承自这几个接口,就具备了发布事件的能力。ApplicationEventPublisher 这个接口只定义了发布事件的方法,但是事件监听器的注册等方法没有,而ApplicationEventMulticaster 里面所有方法都有,AbstractApplicationEventMulticaster 抽象类实现了 ApplicationEventMulticaster 接口的所有方法的抽象类,具体实现类是 SimpleApplicationEventMulticaster
ApplicationEventPublisher定义的事件发布方法,实现类最后都是调用的ApplicationEventMulticaster接口定义的事件发布方法—拆分成两个接口是由于容器只关心事件发布,所以实现这个接口就可以了,具体实现是调ApplicationEventMulticaster接口的实现类完成的
UML.png
public interface ApplicationContext extends EnvironmentCapable, ListableBeanFactory, HierarchicalBeanFactory,
MessageSource, ApplicationEventPublisher, ResourcePatternResolver {
public interface ApplicationEventPublisherAware extends Aware {
/**
* Set the ApplicationEventPublisher that this object runs in.
* <p>Invoked after population of normal bean properties but before an init
* callback like InitializingBean's afterPropertiesSet or a custom init-method.
* Invoked before ApplicationContextAware's setApplicationContext.
* @param applicationEventPublisher event publisher to be used by this object
*/
void setApplicationEventPublisher(ApplicationEventPublisher applicationEventPublisher);
}
Bean 可以 通过上面的 ApplicationEventPublisherAware 获取到 ApplicationEventPublisher实例--其实也就是获取到容器这个实例,就可以发布自定义的事件,给容器里面自定义的 EventListener
网友评论