Spring 事件监听机制的核心是基于观察者模式(Observer Pattern) 实现的组件间解耦通信机制,通过事件(Event)、监听器(Listener)、事件发布者(Publisher) 三者的协作,实现 “发布 - 订阅” 式的交互。其核心目标是让组件之间无需直接依赖,通过事件传递信息,从而降低耦合度。
Spring 事件监听机制的核心由以下 4 个部分构成,它们协同工作完成事件的发布与处理:
事件是传递数据的载体,所有事件需直接或间接继承 Spring 提供的ApplicationEvent
类(Spring 4.2 + 后可省略继承,支持任意对象作为事件)。
- 内置事件:Spring 定义了一系列容器生命周期相关的事件(如
ContextRefreshedEvent
容器初始化完成、ContextClosedEvent
容器关闭等),用于通知容器状态变化。
- 自定义事件:用户可通过继承
ApplicationEvent
定义业务事件,携带业务数据(如OrderCreatedEvent
订单创建事件,包含订单 ID、用户信息等)。
示例:自定义订单创建事件
public class OrderCreatedEvent extends ApplicationEvent {private Long orderId;private String username;
监听器是事件的 “订阅者”,负责定义事件发生后的处理逻辑。Spring 中监听器的实现方式有两种:
- 实现
ApplicationListener
接口:泛型指定监听的事件类型,重写onApplicationEvent
方法处理事件。
- 使用
@EventListener
注解:在方法上标注该注解,并指定监听的事件类型(更简洁,推荐)。
监听器需要被 Spring 容器管理(如标注@Component
),才能被识别并注册。
示例:监听订单创建事件的监听器
@Component
public class OrderListener {
事件发布者是 “发布者”,负责在特定时机发布事件。Spring 中通过ApplicationEventPublisher
接口(或其扩展ApplicationEventPublisherAware
)发布事件。
- 所有 Spring 容器(
ApplicationContext
)都实现了ApplicationEventPublisher
接口,因此可直接在 Bean 中注入ApplicationEventPublisher
用于发布事件。
示例:发布订单创建事件
@Service
public class OrderService {
ApplicationEventMulticaster
是 Spring 事件机制的 “中枢”,负责管理所有监听器和分发事件,是连接发布者和监听器的核心组件。其工作流程如下:
- 注册监听器:Spring 容器启动时,会自动扫描所有监听器(
ApplicationListener
或@EventListener
标注的 Bean),并将它们注册到ApplicationEventMulticaster
中。
- 分发事件:当发布者调用
publishEvent
发布事件时,事件会被传递给ApplicationEventMulticaster
;它根据事件类型,找到所有匹配的监听器(监听该事件或其父类事件的监听器),并触发监听器的处理方法。
Spring 默认的ApplicationEventMulticaster
实现是SimpleApplicationEventMulticaster
,支持同步和异步两种事件分发方式:
- 同步(默认):事件发布后,会立即执行所有监听器的逻辑,直到全部完成(发布者会阻塞等待)。
- 异步:通过配置
TaskExecutor
,可让监听器在独立线程中执行,发布者无需等待(需在@EventListener
上标注@Async
,并配置线程池)。
Spring 事件监听的完整流程可概括为:
- 定义事件:通过
ApplicationEvent
子类或普通对象封装业务数据。
- 注册监听器:监听器被 Spring 容器扫描并注册到
ApplicationEventMulticaster
。
- 发布事件:业务逻辑中通过
ApplicationEventPublisher
发布事件。
- 分发与处理:
ApplicationEventMulticaster
接收事件,找到匹配的监听器,触发其处理方法(同步或异步)。
- 解耦:发布者与监听器无需互相依赖,通过事件间接通信,降低组件耦合度。
- 扩展性:新增业务逻辑(如订单创建后新增 “发送邮件” 功能)只需添加新的监听器,无需修改发布者代码。
- 灵活性:支持同步 / 异步处理,可根据业务需求选择(如耗时操作适合异步)。
这一机制在 Spring 内部被广泛使用(如容器生命周期管理),也常用于业务系统中跨组件通信(如订单流程、消息通知等场景)。