第九篇・Spring 5 源码深度拆解:Spring 事件驱动模型
👋 前言
前面我们已经叨叨完:IOC、生命周期、循环依赖、AOP、事务、SpringMVC、Boot 自动配置、资源加载与 Environment。
Spring 内部也存在靠事件驱动解耦的:容器启动、刷新、容器刷新(refresh)完成后发布 ContextRefreshedEvent,此时所有 Bean 均已初始化完毕,是最常用的启动后逻辑入口……这一篇我们梳理事件模型,了解掌握 Spring 轻量但极其重要的扩展机制。
即刻起简单又轻松。
一、核心角色
- ApplicationEvent:事件本身(所有事件的父类)
- ApplicationListener:事件监听器(观察者)
- ApplicationEventPublisher:事件发布器(被观察者)
- ApplicationContext:本身就是发布器,内部维护监听器
- ApplicationEventMulticaster:Spring 通过
AbstractApplicationContext.initApplicationEventMulticaster()方法初始化事件多播器。默认创建的是SimpleApplicationEventMulticaster实例;同时还承担了事件匹配和路由的重要职责——它需要根据事件类型找到对应的监听器进行派发
二、最简流程
- 定义事件
- extends ApplicationEvent 经典方式
- 直接使用任意pojo
- 定义监听器 implements ApplicationListener
- 容器启动时收集所有监听器
- 调用 publishEvent 发布
- Spring 遍历匹配监听器执行 onApplicationEvent
三、Spring 内置核心事件
- ContextRefreshedEvent:容器完全刷新完成(Bean 都初始化好了)
- ContextStartedEvent:容器启动
- ContextStoppedEvent:容器停止
- ContextClosedEvent:容器关闭(单例 Bean 销毁前)
- RequestHandledEvent:SpringMVC 请求处理完成
最常用:ContextRefreshedEvent很多框架启动逻辑都监听它。
四、源码级流程:事件是怎么被发布和消费的?
核心调用链
// 1. 发布入口publishEvent(Object event)↓// 2. 获取事件类型,包装为 ApplicationEvent(若 event 本身不是)getApplicationEventMulticaster()↓// 3. 多播器开始派发multicastEvent(ApplicationEvent event, ResolvableType eventType)↓// 4. 获取所有匹配的监听器getApplicationListeners(event, type)↓// 5. 遍历监听器,逐个调用invokeListener(listener, event)↓// 6. 最终执行监听器的回调listener.onApplicationEvent(event)
1. 发布入口:publishEvent
几乎所有地方最终都会走到:
// AbstractApplicationContextprotectedvoidpublishEvent(Object event, @Nullable ResolvableType typeHint) {// 1. 包装成 ApplicationEventApplicationEvent applicationEvent = null;if (event instanceof ApplicationEvent) {applicationEvent = (ApplicationEvent) event;} else {applicationEvent = new PayloadApplicationEvent<>(this, event);}// 2. 获取多播器ApplicationEventMulticaster multicaster = this.applicationEventMulticaster;// 3. 多播事件:发给所有匹配监听器multicaster.multicastEvent(applicationEvent, typeHint);}
2. 事件多播核心:SimpleApplicationEventMulticaster
@OverridepublicvoidmulticastEvent(ApplicationEvent event, @Nullable ResolvableType typeHint) {ResolvableType eventType = (typeHint != null ? typeHint : resolveDefaultEventType(event));Executor executor = getTaskExecutor();for (ApplicationListener<?> listener : getApplicationListeners(event, eventType)) {if (executor != null) {executor.execute(() -> invokeListener(listener, event));} else {invokeListener(listener, event);}}}
3. 最终执行监听器
privatevoiddoInvokeListener(ApplicationListener listener, ApplicationEvent event) {listener.onApplicationEvent(event);}
五、@EventListener 注解原理
1. 解析器:EventListenerMethodProcessor
EventListenerMethodProcessor 实现 SmartInitializingSingleton 接口,在容器所有单例 Bean 完成实例化、依赖注入、初始化之后,执行 afterSingletonsInstantiated();SmartInitializingSingleton.afterSingletonsInstantiated() 的触发时机是“所有单例 Bean 实例化完成之后的一次性回调;而实例化、依赖注入、初始化是bean生命周期中更早阶段发生的事情。
2. 核心流程
- 遍历所有单例 Bean
- 找出带
@EventListener的方法 - 解析监听的事件类型
- 包装成
ApplicationListenerMethodAdapter - 注册到
ApplicationEventMulticaster
3. 执行时
发布事件 → 匹配 adapter → 反射调用你写的 @EventListener 方法。
六、异步事件 @Async + 事件
Spring 事件默认是同步执行的(发布者线程阻塞直到所有监听器执行完毕)。
开启步骤
- 全局异步(所有事件都异步)
重写 applicationEventMulticaster Bean,为其设置 TaskExecutor:
配置后,所有事件的派发都会提交到线程池中执行,发布者线程立即返回。
@Configurationpublic class AsyncEventConfig {@Bean(name = "applicationEventMulticaster")public ApplicationEventMulticaster applicationEventMulticaster() {SimpleApplicationEventMulticaster multicaster = new SimpleApplicationEventMulticaster();multicaster.setTaskExecutor(Executors.newFixedThreadPool(5)); // 设置线程池return multicaster;}}
- 局部异步启动类加
@EnableAsync
@EnableAsync // 启动类或配置类上添加@SpringBootApplicationpublic classApplication{ ... }@Componentpublic classOrderEventListener{@Async // 仅此监听器异步执行@EventListenerpublic void handleOrder(OrderEvent event) {// 异步处理逻辑}}
- 配置
TaskExecutorBean (可选但强烈建议配置) - 监听方法上加
@Async
可自定义 TaskExecutor Bean 控制线程池,不配置则使用默认的 SimpleAsyncTaskExecutor(每个任务新建线程,不推荐生产环境使用)。
原理
多播时判断有 executor 就提交线程池,不阻塞主线程。
七、事务绑定事件 @TransactionalEventListener
核心:TransactionSynchronization
若发布事件时不存在事务,默认直接执行,可通过 fallbackExecution 控制。
原理:
- 不立即执行监听方法
- 把执行逻辑挂到事务同步管理器
- 等事务 提交 / 回滚 / 完成 后再执行
常用阶段
- BEFORE_COMMIT
- AFTER_COMMIT
- AFTER_ROLLBACK
- AFTER_COMPLETION
这是微服务 / 分布式事务里非常实用的 “事务完成后再发消息” 方案。
八、Spring 事件完整总结
- 事件:ApplicationEvent
- 监听:ApplicationListener / @EventListener
- 发布:ApplicationContext.publishEvent
- 调度:ApplicationEventMulticaster
- 异步:@Async + TaskExecutor
- 事务绑定:@TransactionalEventListener
- 内置事件:启动 / 刷新 / 停止 / 关闭
轻量、解耦、无侵入,是 Spring 内部和业务扩展最常用的机制之一。
下篇预告
第十篇・Spring 5 源码深度拆解:Spring 类型转换与校验体系
- Converter、ConversionService 类型转换
- Formatter、PropertyEditor 传统绑定
- @Valid、Validator 校验底层原理
- SpringMVC 参数自动绑定核心逻辑
- 自定义类型转换器实战补齐参数绑定、数据绑定最后一块拼图。
夜雨聆风