Spring事件驱动
Spring 事件驱动的代码都位于spring-context 模块的event包中,主要包括:事件(Event)发布者() Publisher) ,订阅者(Listener)组成。
事件
ApplicationEvent
java的所有事件对象一般都是java.util.EventObject的子类,Spring的整个继承体系如下:
Publisher 发布者
ApplicationEventPublisher
AbstractApplicationContext实现了ApplicationEventPublisher接口 publishEvent
ApplicationEventMulticaster
ApplicationEventPublisher实际上正是将请求委托给ApplicationEventMulticaster来实现的。其继承体系:
Listeners 监听者
所有的监听器是jdk EventListener的子类,这是一个mark接口。继承体系:
可以看出SmartApplicationListener和GenericApplicationListener是高度相似的,都提供了事件类型检测和顺序机制,而后者是从Spring4.2加入的,Spring官方文档推荐使用后者代替前者。
初始化
前面说过AppjlicationEventPublisher是通过委托给ApplicationEventMulticaster实现的,所以refresh方法中完成的是对ApplicationEventMulticaster的初始化:
1 | // Initialize event multicaster for this context. |
initApplicationEventMulticaster则首先在BeanFactory中寻找ApplicationEventMulticaster的bean,如果找到,那么调用getBean方法将其初始化,如果找不到那么使用SimpleApplicationEventMulticaster。
ApplicationEventPublisher 接口
AbstractApplicationContext.publishEvent核心代码:
1 | protected void publishEvent(Object event, ResolvableType eventType) { |
SimpleApplicationEventMulticaster.multicastEvent:
1 |
|
监听器获取
获取当然还是通过beanFactory的getBean来完成的,值得注意的是Spring在此处使用了缓存(ConcurrentHashMap)来加速查找的过程。
同步/异步
可以看出,如果executor不为空,那么监听器的执行实际上是异步的。那么如何配置同步/异步呢?
全局
1 | <task:executor id="multicasterExecutor" pool-size="3"/> |
task schema是Spring从3.0开始加入的,使我们可以不再依赖于Quartz实现定时任务,源码在org.springframework.core.task包下,使用需要引入schema:
1 | xmlns:task="http://www.springframework.org/schema/task" |
开启注解支持:
1 | <!-- 开启@AspectJ AOP代理 --> |
在代码中使用示例:
1 |
|