Spring事件監聽機制

  • 2019 年 10 月 5 日
  • 筆記

前言

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

可以看到也沒啥特殊的,無非就是起個執行緒池去調用這些監聽器的方法

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