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做一个统一的处理,通过继承关系来判断。
获取到需要执行的监听后,会使用映射调用统一的接口方法,执行具体的监听实现逻辑。