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;    }}

来源:https://www.icode9.com/content-4-839601.html

(0)

相关推荐