关于事件驱动模型和观察者模型相关内容:事件驱动模型与观察者模式
1、Spring事件驱动模型
如上图:
ApplicationListener
:Spring事件驱动中的监听器基类接口,也即是观察者,事件消费者的基类接口;通过实现onApplicationEvent
方法实现事件监听逻辑;ApplicationEventPublisher
:定义了事件的发布接口,即事件源,事件生产者,ApplicationContext类继承类该接口;这里只定义了事件发布规范,具体的实现交由ApplicationEventMulticaster
广播发布器的multicastEvent
方法来实现。ApplicationEvent
:事件对象,Spring事件驱动模型的对象源。其中的source属性通常用来携带事件源;所有需要使用事件驱动模型的事件都可以继承此类。
2、Spring中相关事件类
Spring中的事件对象是ApplicationEvent
,该类为Spring事件模型中用于扩展的事件对象,对象中的source属性用来存储事件源,监听器拿到事件对象和事件源之后,对事件作出处理和响应。Spring中部分ApplicationEvent
类如下:
3、Spring事件模型执行原理
3.1、事件发布器的初始化
-
ApplicationContext
中引用了ApplicationEventMulticaster
类,该类可以自定义,如需自定义,在定义bean的时候需要把id设置为:applicationEventMulticaster,才能将自定义的事件发布器注入,原因是AbstractApplicationContext
类代码中定义了这个bean id名称:1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22public static final String APPLICATION_EVENT_MULTICASTER_BEAN_NAME = "applicationEventMulticaster";
...
// 优先尝试获取自定义的时间发布器,找不到,则创建一个默认的SimpleApplicationEventMulticaster事件发布器
protected void initApplicationEventMulticaster() {
ConfigurableListableBeanFactory beanFactory = getBeanFactory();
if (beanFactory.containsLocalBean(APPLICATION_EVENT_MULTICASTER_BEAN_NAME)) {
this.applicationEventMulticaster =
beanFactory.getBean(APPLICATION_EVENT_MULTICASTER_BEAN_NAME, ApplicationEventMulticaster.class);
if (logger.isTraceEnabled()) {
logger.trace("Using ApplicationEventMulticaster [" + this.applicationEventMulticaster + "]");
}
}
else {
this.applicationEventMulticaster = new SimpleApplicationEventMulticaster(beanFactory);
beanFactory.registerSingleton(APPLICATION_EVENT_MULTICASTER_BEAN_NAME, this.applicationEventMulticaster);
if (logger.isTraceEnabled()) {
logger.trace("No '" + APPLICATION_EVENT_MULTICASTER_BEAN_NAME + "' bean, using " +
"[" + this.applicationEventMulticaster.getClass().getSimpleName() + "]");
}
}
}
3.2、事件的发布
事件发布的时候,调用AbstractApplicationContext
的publishEvent(Object event, @Nullable ResolvableType eventType)
方法,该方法:
-
将事件转换为ApplicationEvent类型,如果原来不是ApplicationEvent的,则包装为
PayloadApplicationEvent
类型对象; -
调用
getApplicationEventMulticaster().multicastEvent(applicationEvent, eventType)
发布事件; -
如果有父容器,则调用父容器的
publishEvent
方法; -
getApplicationEventMulticaster().multicastEvent(applicationEvent, eventType)
通过eventType检索到对应的监听器,进行后续处理:1
2
3
4
5
6
7
8
9
10
11
12
13
14
public void multicastEvent(final ApplicationEvent event, ResolvableType eventType) {
ResolvableType type = (eventType != null ? eventType : resolveDefaultEventType(event));
// 判断有没有对applicationEventMulticater的taskExecutor进行赋值,有则使用线程池中的线程进行执行invokeListener
Executor executor = getTaskExecutor();
for (ApplicationListener<?> listener : getApplicationListeners(event, type)) {
if (executor != null) {
executor.execute(() -> invokeListener(listener, event));
}
else {
invokeListener(listener, event);
}
}
}
3.3、事件的处理
上面invokeListener
方法中的会调用监听器的onApplicationEvent
方法执行事件的处理。