Spring Event 实现原理
1. Demo
1.1 事件定义
继承 ApplicationEvent 类
import lombok.Getter;
import org.springframework.context.ApplicationEvent;
@Getter
public class EventDemo extends ApplicationEvent {
private String message;
// Object source 具体事件源类
public EventDemo(Object source, String message) {
super(source);
this.message = message;
}
}1.2 事件监听
实现 ApplicationListener 类,并重写 onApplicationEvent() 方法
1.3 事件发布
ApplicationEventPublisher Bean 发布事件
2. 源码分析
2.1 事件是如何发送的?
从 demo 的代码来看 事件是通过
ApplicationEventPublisher类的publishEvent()方法发送的;那么通过断点追踪此方法的行为轨迹,我们会发现其实是调用了AbstractApplicationContext类的publishEvent()方法,那么请看下面的源码。
既然找到了发送事件的入口,那么就先追踪
applicationEventMulticaster()方法
到这里我们只掌握了 ApplicationEventMulticaster 是个接口类,并不知道真正的实现类,而且也没发现关于此接口的构造函数(稍后再揭秘实现类究竟是怎么来的);但是通过断点追踪 multicastEvent() 方法,不难发现其实是调用了 SimpleApplicationEventMulticaster 类的 multicastEvent(),源码如下:
走到这里我们会发现事件的监听者都来自
getApplicationListeners(event, type);通知监听者的其实是
invokeListener(listener, event);
2.2 揭秘如何获取事件对应的监听者
这里同样也会产生一个问题。我们知道 listeners 取自内部类 ListenerRetriever 维护的 applicationListeners 对象,那么 applicationListeners 何时 add 了呢?稍后再揭秘。
总结 获取所有 ApplicationListener 的实现类后,依次判断是否支持给定的事件,也就是事件的类型是否一致;最终通过特定的 cachKey 放置缓存。
2.3 揭秘如何通知事件的监听者
核心代码:listener.onApplicationEvent(event); 拿到监听者的实例,直接调用 onApplicationEvent() 方法
为了揭秘上面两个问题,我们继续观察 AbstractApplicationContext 类,这个类里有我们想要的答案;
也就是说在容器启动过程中会装载ApplicationEventMulticaster,以及存放applicationListeners到容器中。
最后更新于
这有帮助吗?