1.在spring启动流程中,在初始化SpringApplication对象时,会先通过SPI方式获取所有的监听类(就是通过classLoad类,读取classPath路径所有META-INF/spring.factories文件,然后取出ApplicationListener的properties)。这个监听如何运行?就通过Spring EventPublishingRunListener对象了(网上学名叫:事件的传播)。

 

 

 

 图一:SpringApplication的构造函数,获取所有监听

 

2.然后在启动流程run()方法中,会先获取EventPublishingRunListener对象,然后循环执行前面获取的监听。

 

图二:Spring启动流程中的run方法

 

图三:EventPublishingRunListener类图

3.如何循环监听?接下来可以看EventPublishingRunListener对象的内部逻辑:

   private final SpringApplication application;
  private final String[] args;

   private final SimpleApplicationEventMulticaster initialMulticaster; // 真正运行监听的类
  /**
   * EventPublishingRunListener构造函数会接受SpringApplication(监听都放在这个对象里了)和String[]参数
   * @Param SpringApplication 很多spring启动的环境参数都存在这里,如前面获取到的监听类
   * @Param String[] 启动类传进来的参数
   */
public EventPublishingRunListener(SpringApplication application, String[] args) { this.application = application; this.args = args; this.initialMulticaster = new SimpleApplicationEventMulticaster(); for (ApplicationListener<?> listener : application.getListeners()) { this.initialMulticaster.addApplicationListener(listener); // 把listener放到传播器里 } }

  /**
   * 在run()启动流程中,分别会在特定的阶段执行starting(),enviromentPrepared()...等方法
   * 在该方法中会用SpringApplication和args变量构造一个SpringApplicationEvent的子类对象。
   * 在这里是ApplicationStartingEvent,如果执行的是environmentPrepared()方法就会构造ApplicationEnvironmentPreparedEvent对象。
   * SimpleApplicationEventMulticaster对象会根据传入的不同事件对象执行不同的监听

   */
  public void starting() {
   this.initialMulticaster.multicastEvent(new ApplicationStartingEvent(this.application, this.args));
  }

 

 图四:ApplicationEvent类图,在不同的阶段,会构造不同的Event对象

 

 

 4.SimpleApplicationEventMulticaster.multicastEvent()是如何判断要执行哪些监听,哪些不执行的?如下:

 

 

 图五:监听运行入口

 

 

  图六:获取需运行的监听

 

   图七:判断是否需要执行特定监听

如何判单一个监听在当前阶段是否需要运行:

 


  /**
   * 通过该方法来判断当前事件阶段,是否应该运行listener
   */ 
  protected boolean supportsEvent( ApplicationListener<?> listener, ResolvableType eventType, @Nullable Class<?> sourceType) { GenericApplicationListener smartListener = (listener instanceof GenericApplicationListener ? (GenericApplicationListener) listener : new GenericApplicationListenerAdapter(listener)); return (smartListener.supportsEventType(eventType) && smartListener.supportsSourceType(sourceType)); }
  
一般listener实现了
GenericApplicationListener或SmartApplicationListener接口,那么就在listener中具体实现是否在当前阶段执行。否在就会适配为

GenericApplicationListenerAdapter做一个统一的处理,通过继承关系来判断。


 

 

获取到需要执行的监听后,会使用映射调用统一的接口方法,执行具体的监听实现逻辑。