SpringApplication
把启动流程拆分为了以下几个阶段,并提供了相应的回调:
SpringApplicationRunListener
是Spring提供的用于监听SpringApplication
的run
方法的监听器。
Spring Application 启动流程一文中,在分析run
方法源码时,得知SpringApplication
会通过SpringFactoriesLoader
加载声明在/META-INF/spring.factories
配置文件中的SpringApplicationRunListener
并实例化,然后传递给SpringApplicationRunListeners
对象,在run
方法的执行过程中,通过SpringApplicationRunListeners
间隔地调用所有SpringApplicationRunListener
的方法。详情请查阅SpringApplicationRunListeners
相关源码。
SpringApplicationRunListener
由SpringApplicaton
在run
方法是通过SpringFactoriesLoader
从/META-INF/spring.factories
中加载。SpringApplicationRunListener
应该声明一个接收SpringApplication
和String[]
参数的公开的构造函数。package org.springframework.boot;
public interface SpringApplicationRunListener {
default void starting() {
}
default void environmentPrepared(ConfigurableEnvironment environment) {
}
default void contextPrepared(ConfigurableApplicationContext context) {
}
default void contextLoaded(ConfigurableApplicationContext context) {
}
default void started(ConfigurableApplicationContext context) {
}
default void running(ConfigurableApplicationContext context) {
}
default void failed(ConfigurableApplicationContext context, Throwable exception) {
}
}
定义一个实现了SpringApplicationRunListener
接口的类:
package org.springfreamework.boot.demo;
public class MySpringApplicationRunListener implements SpringApplicationRunListener {
public MySpringApplicationRunListener(SpringApplication application, String[] args) {
//...
}
//...
}
SpringApplicationRunListener
的实现类必须声明一个接收SpringApplication
和String[]
类型的构造函数。
在META-INF/spring.factories
文件中添加以下配置:
# Run Listeners
org.springframework.boot.SpringApplicationRunListener=\
org.springfreamework.boot.demo.MySpringApplicationRunListener
在SpringApplication
的run()
方法中,会通过SpringFactoryLoader
加载声明在META-INF/spring.factories
中的SpringApplicationRunListener
实例,并创建一个SpringApplicationRunListeners
的实例,该对象是SpringApplicationRunListener
的集合表现形式,通过SpringApplicationRunListeners
的方法间接调用SpringApplicationRunListener
的方法。
在SpringApplicatin
的run()
方法中,
listeners.starting(bootstrapContext,this.mainApplicationClass);
然后在 prepareEnvironment()
方法中
listeners.environmentPrepared(bootstrapContext,environment);
接着在prepareContext()
方法中
listeners.contextPrepared(context);
//...
listeners.contextLoaded(context);
再着在run()
方法中
listeners.started(context);
最后
listeners.running(context);
如果在上述流程中发生了异常,则在handleRunFailure()
方法中
listeners.failed(context,exception);
Spring Boot内置了唯一的一个EventPublishingRunListener
实现类,该类实现监听Spring Application的运行(run()
)状态,然后发布SpringApplicationEvent
。
EventPublishingRunListener
是Spring提供的内置实现,用于监听SpringApplication运行状态并发布运行事件SpringApplicationEvent
。
package org.springframework.boot.context.event;
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 int getOrder() {
return 0;
}
@Override
public void starting() {
this.initialMulticaster.multicastEvent(new ApplicationStartingEvent(this.application, this.args));
}
@Override
public void environmentPrepared(ConfigurableEnvironment environment) {
this.initialMulticaster
.multicastEvent(new ApplicationEnvironmentPreparedEvent(this.application, this.args, environment));
}
@Override
public void contextPrepared(ConfigurableApplicationContext context) {
this.initialMulticaster
.multicastEvent(new ApplicationContextInitializedEvent(this.application, this.args, context));
}
@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) {
context.publishEvent(new ApplicationStartedEvent(this.application, this.args, context));
AvailabilityChangeEvent.publish(context, LivenessState.CORRECT);
}
@Override
public void running(ConfigurableApplicationContext context) {
context.publishEvent(new ApplicationReadyEvent(this.application, this.args, context));
AvailabilityChangeEvent.publish(context, ReadinessState.ACCEPTING_TRAFFIC);
}
@Override
public void failed(ConfigurableApplicationContext context, Throwable exception) {
ApplicationFailedEvent event = new ApplicationFailedEvent(this.application, this.args, context, exception);
if (context != null && context.isActive()) {
// Listeners have been registered to the application context so we should
// use it at this point if we can
context.publishEvent(event);
} else {
// An inactive context may not have a multicaster so we use our multicaster to
// call all of the context's listeners instead
if (context instanceof AbstractApplicationContext) {
for (ApplicationListener<?> listener : ((AbstractApplicationContext) context)
.getApplicationListeners()) {
this.initialMulticaster.addApplicationListener(listener);
}
}
this.initialMulticaster.setErrorHandler(new LoggingErrorHandler());
this.initialMulticaster.multicastEvent(event);
}
}
private static class LoggingErrorHandler implements ErrorHandler {
private static final Log logger = LogFactory.getLog(EventPublishingRunListener.class);
@Override
public void handleError(Throwable throwable) {
logger.warn("Error calling ApplicationEventListener", throwable);
}
}
}
从上述代码中可以发现,Spring内置了以下SpringApplicationEvent
:
SpringApplicationEvent | 触发顺序 | 含义 |
---|---|---|
ApplicationStartingEvent | 1 | 启动事件 |
ApplicationEnvironmentPreparedEvent | 2 | 环境准备事件 |
ApplicationContextInitializedEvent | 3 | 应用上下文初始化事件 |
ApplicationPreparedEvent | 4 | 准备事件 |
ApplicationStartedEvent | 5 | 启动完成事件 |
ApplicationReadyEvent | 6 | 准备完成事件 |
ApplicationFailedEvent | -1 | 失败事件 |