Spring事件监听机制

55次阅读

共计 4924 个字符,预计需要花费 13 分钟才能阅读完成。

前言

Spring 中的事件机制其实就是设计模式中的观察者模式,主要由以下角色构成:

  1. 事件
  2. 事件监听器(监听并处理事件)
  3. 事件发布者(发布事件)

首先看一下监听器和发布者的接口定义

public interface ApplicationListener<E extends ApplicationEvent> extends EventListener {void onApplicationEvent(E event);
  }
  
  public interface ApplicationEventPublisher {default void publishEvent(ApplicationEvent event) {publishEvent((Object) event);
    }
    void publishEvent(Object event);

}

事件流转流程

初始化事件广播器

看一下这个方法AbstractApplicationContext.refresh,在 IOC 源码解析那篇文章已经把这个方法分析完了,所以直接关注事件广播器和事件发布相关的逻辑即可


 public void refresh() throws BeansException, IllegalStateException {synchronized (this.startupShutdownMonitor) {
            // Prepare this context for refreshing.
            prepareRefresh();
 
            // Tell the subclass to refresh the internal bean factory.
            ConfigurableListableBeanFactory beanFactory = obtainFreshBeanFactory();
 
            // Prepare the bean factory for use in this context.
            prepareBeanFactory(beanFactory);
 
            try {
                // Allows post-processing of the bean factory in context subclasses.
                postProcessBeanFactory(beanFactory);
 
                // Invoke factory processors registered as beans in the context.
                invokeBeanFactoryPostProcessors(beanFactory);
 
                // Register bean processors that intercept bean creation.
                registerBeanPostProcessors(beanFactory);
 
                // Initialize message source for this context.
                initMessageSource();
 
                // 初始化事件广播器
                initApplicationEventMulticaster();
 
                // Initialize other special beans in specific context subclasses.
                onRefresh();
 
                // Check for listener beans and register them.
                registerListeners();
 
                // Instantiate all remaining (non-lazy-init) singletons.
                finishBeanFactoryInitialization(beanFactory);
 
                // 发布事件
                finishRefresh();}
 
            catch (BeansException ex) {logger.warn("Exception encountered during context initialization - cancelling refresh attempt", ex);
 
                // Destroy already created singletons to avoid dangling resources.
                destroyBeans();
 
                // Reset 'active' flag.
                cancelRefresh(ex);
 
                // Propagate exception to caller.
                throw ex;
            }
        }
}

protected void initApplicationEventMulticaster() {ConfigurableListableBeanFactory beanFactory = getBeanFactory();
        if (beanFactory.containsLocalBean(APPLICATION_EVENT_MULTICASTER_BEAN_NAME)) {
            this.applicationEventMulticaster =
                    beanFactory.getBean(APPLICATION_EVENT_MULTICASTER_BEAN_NAME, ApplicationEventMulticaster.class);
            if (logger.isDebugEnabled()) {logger.debug("Using ApplicationEventMulticaster [" + this.applicationEventMulticaster + "]");
            }
        }
        else {this.applicationEventMulticaster = new SimpleApplicationEventMulticaster(beanFactory);
            beanFactory.registerSingleton(APPLICATION_EVENT_MULTICASTER_BEAN_NAME, this.applicationEventMulticaster);
            if (logger.isDebugEnabled()) {
                logger.debug("Unable to locate ApplicationEventMulticaster with name'" +
                        APPLICATION_EVENT_MULTICASTER_BEAN_NAME +
                        "': using default [" + this.applicationEventMulticaster + "]");
            }
        }
    }

可以看到如果没有自定义的事件广播器,默认是使用 SimpleApplicationEventMulticaster

发布事件

发布事件是在 bean 的初始化之后的


    protected void finishRefresh() {
        // Initialize lifecycle processor for this context.
        initLifecycleProcessor();
 
        // Propagate refresh to lifecycle processor first.
        getLifecycleProcessor().onRefresh();
 
        // 发布事件
        publishEvent(new ContextRefreshedEvent(this));
 
        // Participate in LiveBeansView MBean, if active.
        LiveBeansView.registerApplicationContext(this);
    }


public void publishEvent(ApplicationEvent event) {Assert.notNull(event, "Event must not be null");
        if (logger.isTraceEnabled()) {logger.trace("Publishing event in" + getDisplayName() + ":" + event);
        }
        //1. 获取到事件广播器,发布事件
        getApplicationEventMulticaster().multicastEvent(event);
        //2. 如果存在父容器,父容器也将发布事件
        if (this.parent != null) {this.parent.publishEvent(event);
        }
    }

具体的发布逻辑在 multicastEvent 方法中


public void multicastEvent(final ApplicationEvent event) {
        // 遍历执行 listener,getApplicationListeners 调用 AbstractApplicationEventMulticaster 父类方法
        for (final ApplicationListener listener : getApplicationListeners(event)) {Executor executor = getTaskExecutor();
            if (executor != null) {executor.execute(new Runnable() {
                    @Override
                    public void run() {listener.onApplicationEvent(event);
                    }
                });
            }
            else {listener.onApplicationEvent(event);
            }
        }
    }

可以看到也没啥特殊的,无非就是起个线程池去调用这些监听器的方法

而监听器的处理就看各个监听器的具体实现了

正文完
 0