Spring源码-SpringBoot-启动流程-Event-Listener-Publisher-SpringApplicationEvent与SpringApplicationRunListener

总结摘要
SpringBoot启动流程事件监听发布

前言

<font style="color:rgba(0, 0, 0, 0.9);">SpringApplicationEvent</font>是与 <font style="color:rgba(0, 0, 0, 0.9);background-color:rgba(0, 0, 0, 0.03);">SpringApplication</font> 相关的 <font style="color:rgba(0, 0, 0, 0.9);background-color:rgba(0, 0, 0, 0.03);">ApplicationEvent</font> 的基类。

监听器事件类型

共7个子类(实现类)。

序号名称StepName关联事件类型描述
1应用启动开始spring.boot.application.startingApplicationStartingEvent应用开始启动,进行最基础的初始化
2环境准备完成spring.boot.application.environment-preparedApplicationEnvironmentPreparedEvent配置加载完成,环境变量就绪
3上下文准备完成spring.boot.application.context-preparedApplicationContextInitializedEvent应用上下文创建完成,初始化器已执行
4上下文加载完成spring.boot.application.context-loadedApplicationPreparedEventBean定义加载完成,准备刷新上下文
5应用已启动spring.boot.application.startedApplicationStartedEvent上下文刷新完成,核心容器就绪
6应用准备就绪spring.boot.application.readyApplicationReadyEvent所有运行器执行完毕,应用可正常服务
7应用启动失败spring.boot.application.failedApplicationFailedEvent启动过程中出现异常,启动终止

注意,在响应事件完成之后,才能实现事件名称的效果。

例如,ApplicationEnvironmentPreparedEvent事件的响应事件包括加载用户自定义配置文件等。在该事件的响应事件完成之后,才实现”环境准备完成“。

监听器逻辑

事件ApplicationPreparedEventspring.boot.application.context-loaded)及之前,由org.springframework.boot.context.event.EventPublishingRunListener#initialMulticaster响应监听事件,其在EventPublishingRunListener唯一的构造方法中初始化,调用new SimpleApplicationEventMulticaster(),默认单线程同步执行响应逻辑。

事件ApplicationStartedEventspring.boot.application.started)及之后,由方法入参org.springframework.context.ConfigurableApplicationContext响应监听事件,其在步骤refreshContext之后可用。

步骤refreshContext刷新(初始化)了ConfigurableApplicationContext。事件ApplicationPreparedEvent是步骤refreshContext前的最后一个监听事件,ApplicationStartedEventspring.boot.application.started)是步骤refreshContext后的第一个监听事件。

关键类信息

SpringApplicationRunListeners

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
// org.springframework.boot.SpringApplicationRunListeners
class SpringApplicationRunListeners {

	private final Log log;

	private final List<SpringApplicationRunListener> listeners;

	private final ApplicationStartup applicationStartup;

	SpringApplicationRunListeners(Log log, Collection<? extends SpringApplicationRunListener> listeners,
			ApplicationStartup applicationStartup) {
		this.log = log;
		this.listeners = new ArrayList<>(listeners);
		this.applicationStartup = applicationStartup;
	}


	void contextLoaded(ConfigurableApplicationContext context) {
		doWithListeners("spring.boot.application.context-loaded", (listener) -> listener.contextLoaded(context));
	}

	void started(ConfigurableApplicationContext context, Duration timeTaken) {
		doWithListeners("spring.boot.application.started", (listener) -> listener.started(context, timeTaken));
	}

	private void doWithListeners(String stepName, Consumer<SpringApplicationRunListener> listenerAction) {
		doWithListeners(stepName, listenerAction, null);
	}

	private void doWithListeners(String stepName, Consumer<SpringApplicationRunListener> listenerAction,
			Consumer<StartupStep> stepAction) {
		StartupStep step = this.applicationStartup.start(stepName);
		this.listeners.forEach(listenerAction);
		if (stepAction != null) {
			stepAction.accept(step);
		}
		step.end();
	}    
}

SpringApplicationRunListener

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
// org.springframework.boot.SpringApplicationRunListener
// org.springframework.boot.context.event.EventPublishingRunListener
// public class EventPublishingRunListener implements SpringApplicationRunListener, Ordered {}

// `EventPublishingRunListener` 是`SpringApplicationRunListener`的唯一实现。

// org.springframework.boot.context.event.EventPublishingRunListener
public class EventPublishingRunListener implements SpringApplicationRunListener, Ordered {

	private final SpringApplication application;

	private final String[] args;
    
	private final SimpleApplicationEventMulticaster initialMulticaster;

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

    // 
	@Override
	public void contextLoaded(ConfigurableApplicationContext context) {
		for (ApplicationListener<?> listener : this.application.getListeners()) {
			if (listener instanceof ApplicationContextAware) {
				((ApplicationContextAware) listener).setApplicationContext(context);
			}
			context.addApplicationListener(listener);
		}
		this.initialMulticaster.multicastEvent(new ApplicationPreparedEvent(this.application, this.args, context));
	}

    // 
	@Override
	public void started(ConfigurableApplicationContext context, Duration timeTaken) {
		context.publishEvent(new ApplicationStartedEvent(this.application, this.args, context, timeTaken));
		AvailabilityChangeEvent.publish(context, LivenessState.CORRECT);
	}
}


// 类描述
// org.springframework.context.event.ApplicationEventMulticaster
// org.springframework.context.event.AbstractApplicationEventMulticaster
// org.springframework.context.event.SimpleApplicationEventMulticaster
// `SimpleApplicationEventMulticaster`是`ApplicationEventMulticaster`的唯一实现,`AbstractApplicationEventMulticaster`是抽象类。

// 初始化时机
--> org.springframework.context.support.AbstractApplicationContext#refresh
    --> org.springframework.context.support.AbstractApplicationContext#initApplicationEventMulticaster
        --> 优先根据名称`applicationEventMulticaster` beanFactory 中获取
        --> 其次创建`new SimpleApplicationEventMulticaster`并以名称`applicationEventMulticaster`注册到 beanFactory 

END