Spring 事件监听机制

Spring 事件监听机制

我们知道 ApplicationContext 接口继承了ApplicationEventPublisher 接口,能够进行事件发布监听,那么什么是事件的发布跟监听呢?具体实现的原理是啥呢?本文做一个简单的记录。

监听者模式

事件源经过事件的封装传给监听器,当事件源触发事件后,监听器接收到事件对象可以回调事件的方法。

Spring 事件监听机制相关类

  • ApplicationEventPublisher 事件源,负责推送事件,基本都是由子类 AbstractApplicationContext 完成。
  • ApplicationEvent 事件实体,通常都是 ApplicationContextEvent 及其子类。当推送的资源非 ApplicationEvent 时会将资源包装成 PayloadApplicationEvent
  • ApplicationListener 事件监听器。
  • ApplicationEventMulticaster 事件广播器。

执行流程

推送事件

执行 ApplicationEventPublisher 事件源的 publishEvent 方法,通常都是由当前容器 ApplicationContext 的实现类 AbstractApplicationContext#publishEvent 完成。

获取事件广播器

AbstractApplicationContext#getApplicationEventMulticaster

ApplicationEventMulticaster 基础的添加、查询、移除事件监听器的方法都已被 AbstractApplicationEventMulticaster 实现了。如果没有特别指定事件广播器,Spring 默认创建一个 SimpleApplicationEventMulticaster 实例作为事件广播器。

事件广播

SimpleApplicationEventMulticaster#multicastEvent

找到事件对应的监听器完成监听回调。如果「taskExecutor」属性值不为空则会将回调逻辑交给线程池异步执行,通过在配置类上加 @EnableAsync 注解开启异步支持,同时在事件监听方法上加 @Async 注解即可实现异步回调。

注解支持

Spring 4.2 之后可以将 @EventListener 注解加在方法上就能实现事件监听。

实现方式

Spring 是通过回调方法实现的。可以看一下SmartInitializingSingleton 接口的实现类 EventListenerMethodProcessor,在这个类中,会先调用 afterSingletonsInstantiated 方法,然后调用 processBean 方法,在这个方法中会遍历所有容器中所有的 Bean,然后遍历 Bean 中的每一个方法判断方法上是否加了 @EventListener 注解。如果添加了这个注解,就会将这个方法包装成一个 ApplicationListenerMethodAdapter,这个类本身也实现了 ApplicationListener接口,之后将其添加到容器的监听器集合中。