Spring事件監聽機制

前言

Spring中的事件機制其實就是設計模式中的觀察者模式,主要由如下角色構成:設計模式

  1. 事件
  2. 事件監聽器(監聽並處理事件)
  3. 事件發佈者(發佈事件)

首先看一下監聽器和發佈者的接口定義app

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源碼解析那篇文章已經把這個方法分析完了,因此直接關注事件廣播器和事件發佈相關的邏輯便可ide

 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 + "]");
            }
        }
    }

能夠看到若是沒有自定義的事件廣播器,默認是使用SimpleApplicationEventMulticasterpost

發佈事件

發佈事件是在bean的初始化以後的this

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

能夠看到也沒啥特殊的,無非就是起個線程池去調用這些監聽器的方法debug

而監聽器的處理就看各個監聽器的具體實現了 1設計

相關文章
相關標籤/搜索