事件驱动模型通常也被理解成观察者或者发布/订阅模型。
event-source
事件驱动模型的例子很多,如生活中的红绿灯,以及我们在微服务中用到的配置中心,当有配置提交时出发具体的应用实例更新Spring上下文环境。
Spring的事件驱动模型由三部分组成:
Spring 默认对 ApplicationEvent 事件提供了如下实现:
ctx.registerShutdownHook()
注册虚拟机关闭时的钩子才行;eventobject
1public abstract class ApplicationEvent extends EventObject {
2 private static final long serialVersionUID = 7099057708183571937L;
3 //事件发生的时间
4 private final long timestamp = System.currentTimeMillis();
5 //创建一个新的ApplicationEvent事件
6 public ApplicationEvent(Object source) {
7 super(source);
8 }
9
10 public final long getTimestamp() {
11 return this.timestamp;
12 }
13}
事件基类ApplicationEvent
,所有的具体事件都会继承该抽象事件类。
ApplicationListener
ApplicationListener
继承自JDK的EventListener
,JDK要求所有监听器将继承它。
1@FunctionalInterface
2public interface ApplicationListener<E extends ApplicationEvent> extends EventListener {
3 void onApplicationEvent(E var1);
4}
提供了onApplicationEvent方法,用以处理ApplicationEvent
,不过对于具体事件的处理需要进行判断。而GenericApplicationListener
和SmartApplicationListener
提供了关于事件更多的元数据信息。
1public class SourceFilteringListener implements GenericApplicationListener, SmartApplicationListener {
2
3 private final Object source;
4
5 @Nullable
6 private GenericApplicationListener delegate;
7
8 //为特定事件源创建SourceFilteringListener,并传入代理的监听器类
9 public SourceFilteringListener(Object source, ApplicationListener<?> delegate) {
10 this.source = source;
11 this.delegate = (delegate instanceof GenericApplicationListener ?
12 (GenericApplicationListener) delegate : new GenericApplicationListenerAdapter(delegate));
13 }
14 //....省略部分代码
15
16 @Override
17 public int getOrder() {
18 return (this.delegate != null ? this.delegate.getOrder() : Ordered.LOWEST_PRECEDENCE);
19 }
20
21 //过滤之后实际处理事件
22 protected void onApplicationEventInternal(ApplicationEvent event) {
23 //...
24 this.delegate.onApplicationEvent(event);
25 }
26
27}
SourceFilteringListener
是ApplicationListener
的装饰器类,过滤特定的事件源。只会注入其事件对应的代理监听器,还提供了按照顺序触发监听器等功能。
在启动的时候会加载一部分 ApplicationListener
。Spring Context加载初始化完成(refresh)后会再次检测应用中的 ApplicationListener
,并且注册,此时会将我们实现的 ApplicationListener
就会加入到 SimpleApplicationEventMulticaster
维护的 Listener 集合中。
Spring也支持直接注解的形式进行事件监听@EventListener(Event.class)
。
EventPublisher
ApplicationContext
接口继承了ApplicationEventPublisher
,并在AbstractApplicationContext
实现了具体代码,实际执行是委托给ApplicationEventMulticaster
。
1@FunctionalInterface
2public interface ApplicationEventPublisher {
3 //通知所有的注册该事件的应用,事件可以是框架事件如RequestHandledEvent或者特定的应用事件。
4 default void publishEvent(ApplicationEvent event) {
5 this.publishEvent((Object)event);
6 }
7
8 void publishEvent(Object var1);
9}
实际的执行是委托给,读者有兴趣可以看一下AbstractApplicationContext
中这部分的逻辑。下面我们具体看一下ApplicationEventMulticaster
接口中定义的方法。
1public interface ApplicationEventMulticaster {
2
3 //增加监听者
4 void addApplicationListener(ApplicationListener<?> listener);
5 //...
6
7 //移除监听者
8 void removeApplicationListener(ApplicationListener<?> listener);
9 //...
10
11 //广播特定事件给监听者
12 void multicastEvent(ApplicationEvent event, @Nullable ResolvableType eventType);
13
14}
AbstractApplicationContext
中定义了对监听者的操作维护,如增加和删除,并提供了将特定事件进行广播的方法。下面看一下具体实现类SimpleApplicationEventMulticaster
。ApplicationContext
自动到本地容器里找一个ApplicationEventMulticaster
实现,如果没有则会使用默认的SimpleApplicationEventMulticaster
。
1public class SimpleApplicationEventMulticaster extends AbstractApplicationEventMulticaster {
2
3 @Nullable
4 private Executor taskExecutor;
5
6 //...
7
8 //用给定的beanFactory创建SimpleApplicationEventMulticaster
9 public SimpleApplicationEventMulticaster(BeanFactory beanFactory) {
10 setBeanFactory(beanFactory);
11 }
12
13 @Override
14 public void multicastEvent(final ApplicationEvent event, @Nullable ResolvableType eventType) {
15 ResolvableType type = (eventType != null ? eventType : resolveDefaultEventType(event));
16 for (final ApplicationListener<?> listener : getApplicationListeners(event, type)) {
17 Executor executor = getTaskExecutor();
18 if (executor != null) {
19 executor.execute(() -> invokeListener(listener, event));
20 }
21 else {
22 invokeListener(listener, event);
23 }
24 }
25 }
26
27 //注入给定事件的给定监听器
28 protected void invokeListener(ApplicationListener<?> listener, ApplicationEvent event) {
29 ErrorHandler errorHandler = getErrorHandler();
30 if (errorHandler != null) {
31 try {
32 doInvokeListener(listener, event);
33 }
34 ...
35 }
36 else {
37 doInvokeListener(listener, event);
38 }
39 }
40
41 @SuppressWarnings({"unchecked", "rawtypes"})
42 private void doInvokeListener(ApplicationListener listener, ApplicationEvent event) {
43 try {
44 listener.onApplicationEvent(event);
45 }
46 //...
47 }
48
49}
在multicastEvent
方法中,executor不为空的情况下,可以看到是支持异步发布事件。发布事件时只需要调用ApplicationContext
中的publishEvent
方法即可进行事件的发布。
本文主要介绍了Spring中的事件驱动模型相关概念。首先介绍事件驱动模型,也可以说是观察者模式,在我们的日常生活中和应用开发中有很多应用。随后重点篇幅介绍了Spring的事件机制,Spring的事件驱动模型由事件、发布者和订阅者三部分组成,结合Spring的源码分析了这三部分的定义与实现。笔者将会在下一篇文章,结合具体例子以及Spring Cloud Config中的实现进行实战讲解。