目录
1. 简介
在深入springboot启动源码之前,我们先学习一下springboot启动过程中的生命周期划分和其中用到的观察者模式。这对我们之后分析启动过程的源码至关重要。同时,我们也可以进一步理解到观察者的使用。
2.springboot启动过程图解
按下图,整个生命周期分为:监听器初始化、环境准备、容器实例化、Bean加载、容器刷新、Runner调用。
在这几个生命周期之间,利用监听器,实现相关的处理。
![在这里插入图片描述](https://img-blog.csdnimg.cn/img_convert/b58ee1e944a2766ed54480d63fa612e2.png
3.观察者模式的具体实现(源码)
springboot启动过程中的观察者模式,主要是用一下几个接口/类实现的:
SpringApplicationRunListeners
类SpringApplicationRunListener
接口(具体实现是org.springframework.boot.context.event.EventPublishingRunListener
)ApplicationListener
(监听器)
3.1 SpringApplicationRunListeners
所有监听器的调用都是通过SpringApplicationRunListeners listeners
对象实现的。在getRunListeners(args)
方法中,会从spring-boot/META-INF/spring.factories
寻找并实例化类。并注入到SpringApplicationRunListeners
的listeners
属性中。
class SpringApplicationRunListeners {
private final Log log;
private final List<SpringApplicationRunListener> listeners;
}
void starting() {
for (SpringApplicationRunListener listener : this.listeners) {
listener.starting();
}
}
//..........以下省略,同上
SpringApplicationRunListeners listeners = getRunListeners(args);
private SpringApplicationRunListeners getRunListeners(String[] args) {
Class<?>[] types = new Class<?>[] { SpringApplication.class, String[].class };
return new SpringApplicationRunListeners(logger,
getSpringFactoriesInstances(SpringApplicationRunListener.class, types, this, args));
}
3.2 EventPublishingRunListener
在EventPublishingRunListener
的实例化中,会实例化一个SimpleApplicationEventMulticaster
对象,并将SpringApplication
中已有的监听器注册到这个广播器中。
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;
}
//发布ApplicationStartingEvent事件
// run方法第一次启动立即被调用。可以用于非常早期的初始化
@Override
public void starting() {
this.initialMulticaster.multicastEvent(new ApplicationStartingEvent(this.application, this.args));
}
//发布ApplicationEnvironmentPreparedEvent事件
//环境environment 准备好之后,容器ApplicationContext创建之前,调用。
@Override
public void environmentPrepared(ConfigurableEnvironment environment) {
this.initialMulticaster
.multicastEvent(new ApplicationEnvironmentPreparedEvent(this.application, this.args, environment));
}
//发布ApplicationContextInitializedEvent事件
//容器已经创建好了,资源加载之前---调用。
@Override
public void contextPrepared(ConfigurableApplicationContext context) {
this.initialMulticaster
.multicastEvent(new ApplicationContextInitializedEvent(this.application, this.args, context));
}
//发布ApplicationPreparedEvent事件
// 容器加载资源之后,在refresh刷新之前 --调用
@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));
}
//发布ApplicationPreparedEvent和AvailabilityChangeEvent事件
//容器启动后,CommandLineRunners和ApplicationRunners还没有执行前--调用
@Override
public void started(ConfigurableApplicationContext context) {
context.publishEvent(new ApplicationStartedEvent(this.application, this.args, context));
AvailabilityChangeEvent.publish(context, LivenessState.CORRECT);
}
//发布ApplicationReadyEvent和AvailabilityChangeEvent事件
//在run()方法结束前,CommandLineRunners和ApplicationRunners执行后--调用
@Override
public void running(ConfigurableApplicationContext context) {
context.publishEvent(new ApplicationReadyEvent(this.application, this.args, context));
AvailabilityChangeEvent.publish(context, ReadinessState.ACCEPTING_TRAFFIC);
}
//发布ApplicationFailedEvent事件
//出现异常时调用
@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);
}
}
}