Spring Boot在启动的整个过程中会有一些逻辑需要处理,实现的方式的就是通过监听器。Spring设计监听器的方式比较简洁,这里的监听器和Servlet的ServletContextListener没有什么关系。
一、官方说明org.springframework.boot.SpringApplicationRunListener
始自Spring Boot 1.0.0
org.springframework.boot.SpringApplication run方法的监听器。所有的SpringApplicationRunListener通过org.springframework.core.io.support.SpringFactoriesLoader加载,并且需要声明一个参数类型为SpringApplication和String[]的public构造函数。每次运行run方法都会new新的SpringApplicationRunListener实例。
监听器的行为分布在整个启动生命周期,
1、starting // run方法刚开始时就调用,用于非常早期的初始化
2、environmentPrepared // env准备好后,context创建之前调用
3、contextPrepared // context创建好但是source(bean)还没有加载
4、contextLoaded // context加载完但是还没有refresh
5、started // context已经refreshed并且application已经启动,org.springframework.boot.CommandLineRunner和org.springframework.boot.ApplicationRunner还未调用
6、running // 在run方法结束之前,context已经refreshed,所有的CommandLineRunner和ApplicationRunner已经调用。
7、failed // application运行失败时
这里从另一个角度归纳了Spring Boot run方法的阶段,对我们从宏观上理解Spring 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) {
}
}
二、实现类
Spring Boot中对SpringApplicationRunListener接口实现的类只有一个:
org.springframework.boot.context.event.EventPublishingRunListener
始自Spring Boot 1.0.0
用于publish org.springframework.boot.context.event.SpringApplicationEvent。使用内部的org.springframework.context.event.ApplicationEventMulticaster来多播已经就绪的事件在context已经refreshed之前。
虽然Spring Boot启动时SpringApplicationRunListener只有一个,但是他是个发布事件的入口,会有其他的listener处理事件,所以重要的逻辑在其他的listener里面。
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));
}
@Override
public void running(ConfigurableApplicationContext context) {
context.publishEvent(new ApplicationReadyEvent(this.application, this.args, context));
}
@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);
}
}
}
这个类里面有一个非常



