Spring事件
Spring事件
事件监听器接口
ApplicationListener 接口
定义了一个方法: onApplicationEvent(E event), 该方法接受 ApplicationEvent 事件对象, 在该方法中编写事件的响应处理逻辑.
事件广播器
当发生容器事件时, 事件广播器将事件通知给事件监听器, 监听器分别对事件进行响应.
ApplicationEventMulticaster
– AbstractApplicationEventMulticaster
– -- SimpleApplicationEventMulticaster
事件监听原理
Spring 在 ApplicationContext 接口的抽象实现类 AbstractApplicationContext 中完成了事件体系的搭建.
AbstractApplicationContext 拥有一个 applicationEventMulticaster 成员变量,
applicationEventMulticaster 提供了容器监听器的注册表.
AbstractApplicationContext 在 refresh() 这个容器启动方法中通过以下三个步骤搭建了事件的基础设施.
// 初始化应用上下文事件广播器initApplicationEventMulticaster()// 注册事件监听器registerListeners()// 完成刷新并发布容器刷新事件refresh()
在 1 处, Spring 初始化事件的广播器.
用户可以在配置文件中为容器定义一个自定义的事件广播器, 只要实现 ApplicationEventMulticaster 就可以了, Spring 会通过反射的机制将其注册成容器的事件广播器, 如果没有找到配置的外部事件广播器, Spring 自动使用 SimpleApplicationEventMulticaster 作为事件广播器
.
在 2 处, 注册 ApplicationListeners
Spring 将根据反射机制, 从 BeanDefinitionRegistry 中找出所有实现 org.springframework.context.ApplicationListener 的 Bean, 将它们注册为容器的事件监听器, 实际的操作就是将其添加到事件广播器所提供的监听器注册表中.
在 3 处, 容器启动完成, 调用事件发布接口向容器中所有的监听器发布事件.
在 publishEvent() 内部, 我们可以看到 Spring 委托 ApplicationEventMulticaster 将事件通知给监听器.
初始化事件广播器 ApplicationEventMulticaster
initApplicationEventMulticaster();
创建一个默认的事件广播器 SimpleApplicationEventMulticaster
public abstract class AbstractApplicationEventMulticaster implements ApplicationEventMulticaster, BeanFactoryAware {private final ListenerRetriever defaultRetriever = new ListenerRetriever(false);}
private class ListenerRetriever { // 事件监听器 public final Set<ApplicationListener> applicationListeners; public final Set<String> applicationListenerBeans; private final boolean preFiltered;}
注册listeners
registerListeners();
在所有注册的 bean中查找实现 ApplicationListener接口的bean,注册到 事件广播器中
org.springframework.context.support.AbstractApplicationContext#registerListeners
protected void registerListeners() { // Register statically specified listeners first. for (ApplicationListener<?> listener : getApplicationListeners()) { getApplicationEventMulticaster().addApplicationListener(listener); } // Do not initialize FactoryBeans here: We need to leave all regular beans // uninitialized to let post-processors apply to them! String[] listenerBeanNames = getBeanNamesForType(ApplicationListener.class, true, false); for (String lisName : listenerBeanNames) { getApplicationEventMulticaster().addApplicationListenerBean(lisName); }}
发布通知
finishRefresh();
完成刷新过程, 通知生命周期处理器 lifecycleProcessor 刷新过程, 同时发出 ContextRefreshEvent事件通知
Finish the refresh of this context, invoking the LifecycleProcessor’s
onRefresh() method and publishing the
protected void finishRefresh() { // Initialize lifecycle processor for this context.创建 DefaultLifecycleProcessor initLifecycleProcessor(); // Propagate refresh to lifecycle processor first. getLifecycleProcessor().onRefresh(); // Publish the final event. publishEvent(new ContextRefreshedEvent(this)); // Participate in LiveBeansView MBean, if active. LiveBeansView.registerApplicationContext(this);}
手动发布事件通知
ctx.publishEvent(eventType);
根据事件类型 获取 匹配的 ApplicationListener 列表,调用其 listener.onApplicationEvent(event)
方法.
public void publishEvent(ApplicationEvent event) { // 发布通知 getApplicationEventMulticaster().multicastEvent(event); if (this.parent != null) { this.parent.publishEvent(event); }}public void multicastEvent(final ApplicationEvent event) { for (final ApplicationListener listener : getApplicationListeners(event)) { Executor executor = getTaskExecutor(); if (executor != null) { // 若有executor,则在executor里执行 executor.execute(new Runnable() { public void run() { listener.onApplicationEvent(event); } }); } else { listener.onApplicationEvent(event); // 回调 listener.onApplicationEvent() 方法 } }}// 获取和传入的 ApplicationEvent 匹配的 ApplicationListener 列表protected Collection<ApplicationListener> getApplicationListeners(ApplicationEvent event) { Class<? extends ApplicationEvent> eventType = event.getClass(); // 获取事件类型Class Object source = event.getSource(); Class<?> sourceType = (source != null ? source.getClass() : null); ListenerCacheKey cacheKey = new ListenerCacheKey(eventType, sourceType); ListenerRetriever retriever = this.retrieverCache.get(cacheKey); if (retriever != null) { // 若缓存中有,直接返回缓存中的 listeners return retriever.getApplicationListeners(); } else { // 缓存中没有 retriever = new ListenerRetriever(true); LinkedList<ApplicationListener> allListeners = new LinkedList<ApplicationListener>(); Set<ApplicationListener> listeners; Set<String> listenerBeans; synchronized (this.defaultRetriever) { listeners = new LinkedHashSet<ApplicationListener>(this.defaultRetriever.applicationListeners); listenerBeans = new LinkedHashSet<String>(this.defaultRetriever.applicationListenerBeans); } for (ApplicationListener listener : listeners) { // 遍历所有listeners if (supportsEvent(listener, eventType, sourceType)) { // 若该listener支持该Event retriever.applicationListeners.add(listener); allListeners.add(listener); // 添加listener } } if (!listenerBeans.isEmpty()) { BeanFactory beanFactory = getBeanFactory(); for (String listenerBeanName : listenerBeans) { ApplicationListener listener = beanFactory.getBean(listenerBeanName, ApplicationListener.class); if (!allListeners.contains(listener) && supportsEvent(listener, eventType, sourceType)) { retriever.applicationListenerBeans.add(listenerBeanName); allListeners.add(listener); } } } OrderComparator.sort(allListeners); // listener排序 this.retrieverCache.put(cacheKey, retriever); return allListeners; }}