此章节主要对springboot启动过程中,发生的【初始化启动上下文】、【初始化监听器列表】、【发布springboot开始启动事件】进行源码解析,对应的代码如图1所示:
图1:
// 首先初始化一个计时器,并开始计时
StopWatch stopWatch = new StopWatch();
stopWatch.start();
// 初始化启动上下文
DefaultBootstrapContext bootstrapContext = createBootstrapContext();
ConfigurableApplicationContext context = null;
// 设置系统参数:java.awt.headless(在系统可能缺少显示设备、键盘或鼠标这些外设的情况下可以使用该模式,例如Linux服务器)
configureHeadlessProperty();
// 初始化监听器列表
SpringApplicationRunListeners listeners = getRunListeners(args);
// 发布springboot开始启动事件
listeners.starting(bootstrapContext, this.mainApplicationClass);
图2:
private DefaultBootstrapContext createBootstrapContext() {
DefaultBootstrapContext bootstrapContext = new DefaultBootstrapContext();
this.bootstrappers.forEach((initializer) -> initializer.intitialize(bootstrapContext));
return bootstrapContext;
}
点击进入【createBootstrapContext()】方法,可以看到首先获取了一个DefaultBootstrapContext类实例 -> bootstrapContext,然后遍历this.bootstrappers对bootstrapContext进行初始化,由于this.bootstrappers中无任何元素(见springboot启动源码解析(一):SpringApplication初始化),故对bootstrapContext未执行任何操作,最后将bootstrapContext返回。
图3:
private void configureHeadlessProperty() {
System.setProperty(SYSTEM_PROPERTY_JAVA_AWT_HEADLESS,
System.getProperty(SYSTEM_PROPERTY_JAVA_AWT_HEADLESS, Boolean.toString(this.headless)));
}
在系统可能缺少显示设备、键盘或鼠标这些外设的情况下可以使用该模式,例如Linux服务器
图4:
private SpringApplicationRunListeners getRunListeners(String[] args) {
Class>[] types = new Class>[] { SpringApplication.class, String[].class };
return new SpringApplicationRunListeners(logger,
getSpringFactoriesInstances(SpringApplicationRunListener.class, types, this, args),
this.applicationStartup);
}
在【getRunListeners】方法中,一共进行了3步操作:
1、获取了一个class数组types
其中的元素分别为:SpringApplication和String数组的class对象,types主要用于在后序反射初始化对象时,获取到目标的构造方法。
2、获取SpringApplicationRunListener实例对象。
【getSpringFactoriesInstances】方法的目的为:获取并维护SpringApplicationRunListener接口的子类对象列表。在后续的启动过程中,交由listeners发布的事件,实际上是遍历其内部管理的SpringApplicationRunListener对象列表进行发布的。
最终通过getSpringFactoriesInstances获取到的SpringApplicationRunListener类型的对象有且仅有一个:EventPublishingRunListener实例对象。
(getSpringFactoriesInstances解析见:springboot启动源码解析(一):SpringApplication初始化:getSpringFactoriesInstances)
3、通过获取到的SpringApplicationRunListener实例,创建一个SpringApplicationRunListeners对象并返回。
图5:
void starting(ConfigurableBootstrapContext bootstrapContext, Class> mainApplicationClass) {
doWithListeners("spring.boot.application.starting", (listener) -> listener.starting(bootstrapContext),
(step) -> {
if (mainApplicationClass != null) {
step.tag("mainApplicationClass", mainApplicationClass.getName());
}
});
}
private void doWithListeners(String stepName, Consumer listenerAction, Consumer stepAction) {
StartupStep step = this.applicationStartup.start(stepName);
this.listeners.forEach(listenerAction);
if (stepAction != null) {
stepAction.accept(step);
}
step.end();
}
初始化启动上下文和监听器后,通过调用监听器中的starting方法发布【springboot开始启动】事件,在starting方法中,实际通过调用doWithListeners方法对事件进行发布。
1、初始化一个StartupStep实例,并命名为"spring.boot.application.starting",其作用为:追踪“执行时间”或其他指标。
2、对内部维护的监听器列表进行遍历,执行传入的listenerAction。故此处是用EventPublishingRunListener实例对象执行starting(bootstrapContext)方法。
如图6所示,实例化EventPublishingRunListener对象时,在它的构造方法中对成员变量进行了一些初始化操作。初始化initialMulticaster对象时,向其加入了application中维护的9个监听器对象(application监听器的由来详见:springboot启动源码解析(一):SpringApplication初始化),它们分别为:EnvironmentPostProcessorApplicationListener、AnsiOutputApplicationListener、LoggingApplicationListener、BackgroundPreinitializer、DelegatingApplicationListener、ParentContextCloserApplicationListener、ClearCachesApplicationListener、FileEncodingApplicationListener、LiquibaseServiceLocatorApplicationListener
调用EventPublishingRunListener对象的starting方法,实际上是调用了其成员变量initialMulticaster的multicastEvent(ApplicationEvent event)方法。
图6:
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);
}
}
public void starting(ConfigurableBootstrapContext bootstrapContext) {
this.initialMulticaster
.multicastEvent(new ApplicationStartingEvent(bootstrapContext, this.application, this.args));
}
进入initialMulticaster.multicastEvent(ApplicationEvent event)进行查看,如图7所示,
在 multicastEvent(final ApplicationEvent event, ResolvableType eventType)方法中:
1、调用 getApplicationListeners(event, type)能够在initialMulticaster维护的监听器列表中找到匹配该事件的监听器列表
此处符合ApplicationStartingEvent事件的监听器有:LoggingApplicationListener、BackgroundPreinitializer、DelegatingApplicationListener、LiquibaseServiceLocatorApplicationListener
2、对符合要求的监听器进行遍历,执行invokeListener(listener, event)方法
由于在initialMulticaster中,线程池为null,故直接执行invokeListener(listener, event)方法。如图8所示,invokeListener(listener, event)方法实际是调用了listener.onApplicationEvent(event)方法。
当事件为ApplicationStartingEvent时,LoggingApplicationListener、BackgroundPreinitializer、DelegatingApplicationListener、LiquibaseServiceLocatorApplicationListener的onApplicationEvent(event)如图9所示,LoggingApplicationListener初始化了loggingSystem,其它三个listener未执行任何操作
图7:
public void multicastEvent(ApplicationEvent event) {
multicastEvent(event, resolveDefaultEventType(event));
}
/**
* 解析事件类型
*/
private ResolvableType resolveDefaultEventType(ApplicationEvent event) {
return ResolvableType.forInstance(event);
}
/**
* 批量消费事件
*/
public void multicastEvent(final ApplicationEvent event, @Nullable ResolvableType eventType) {
ResolvableType type = (eventType != null ? eventType : resolveDefaultEventType(event));
Executor executor = getTaskExecutor();
for (ApplicationListener> listener : getApplicationListeners(event, type)) {
if (executor != null) {
executor.execute(() -> invokeListener(listener, event));
}
else {
invokeListener(listener, event);
}
}
}
图8:
protected void invokeListener(ApplicationListener> listener, ApplicationEvent event) {
ErrorHandler errorHandler = getErrorHandler();
if (errorHandler != null) {
try {
doInvokeListener(listener, event);
}
catch (Throwable err) {
errorHandler.handleError(err);
}
}
else {
doInvokeListener(listener, event);
}
}
private void doInvokeListener(ApplicationListener listener, ApplicationEvent event) {
try {
listener.onApplicationEvent(event);
}
catch (ClassCastException ex) {
String msg = ex.getMessage();
if (msg == null || matchesClassCastMessage(msg, event.getClass()) ||
(event instanceof PayloadApplicationEvent &&
matchesClassCastMessage(msg, ((PayloadApplicationEvent) event).getPayload().getClass()))) {
Log loggerToUse = this.lazyLogger;
if (loggerToUse == null) {
loggerToUse = LogFactory.getLog(getClass());
this.lazyLogger = loggerToUse;
}
if (loggerToUse.isTraceEnabled()) {
loggerToUse.trace("Non-matching event type for listener: " + listener, ex);
}
}
else {
throw ex;
}
}
}
图9:
/**
* 当listener为LoggingApplicationListener时
*/
public void onApplicationEvent(ApplicationEvent event) {
if (event instanceof ApplicationStartingEvent) {
onApplicationStartingEvent((ApplicationStartingEvent) event);
}
else if (event instanceof ApplicationEnvironmentPreparedEvent) {
onApplicationEnvironmentPreparedEvent((ApplicationEnvironmentPreparedEvent) event);
}
else if (event instanceof ApplicationPreparedEvent) {
onApplicationPreparedEvent((ApplicationPreparedEvent) event);
}
else if (event instanceof ContextClosedEvent
&& ((ContextClosedEvent) event).getApplicationContext().getParent() == null) {
onContextClosedEvent();
}
else if (event instanceof ApplicationFailedEvent) {
onApplicationFailedEvent();
}
}
private void onApplicationStartingEvent(ApplicationStartingEvent event) {
// 初始化loggingSystem
this.loggingSystem = LoggingSystem.get(event.getSpringApplication().getClassLoader());
this.loggingSystem.beforeInitialize();
}
// ---------------------------------------------------------------
/**
* 当listener为BackgroundPreinitializer时,由于未识别到ApplicationStartingEvent事件,故不执行任何操作
*/
public void onApplicationEvent(SpringApplicationEvent event) {
if (!ENABLED) {
return;
}
if (event instanceof ApplicationEnvironmentPreparedEvent
&& preinitializationStarted.compareAndSet(false, true)) {
performPreinitialization();
}
if ((event instanceof ApplicationReadyEvent || event instanceof ApplicationFailedEvent)
&& preinitializationStarted.get()) {
try {
preinitializationComplete.await();
}
catch (InterruptedException ex) {
Thread.currentThread().interrupt();
}
}
}
// ---------------------------------------------------------------
/**
* 当listener为DelegatingApplicationListener时,由于未识别到ApplicationStartingEvent事件,故不执行任何操作
*/
public void onApplicationEvent(ApplicationEvent event) {
if (event instanceof ApplicationEnvironmentPreparedEvent) {
List> delegates = getListeners(
((ApplicationEnvironmentPreparedEvent) event).getEnvironment());
if (delegates.isEmpty()) {
return;
}
this.multicaster = new SimpleApplicationEventMulticaster();
for (ApplicationListener listener : delegates) {
this.multicaster.addApplicationListener(listener);
}
}
if (this.multicaster != null) {
this.multicaster.multicastEvent(event);
}
}
// ---------------------------------------------------------------
/**
* 当listener为LiquibaseServiceLocatorApplicationListener时,由于LIQUIBASE_PRESENT为false,故不执行任何操作
*/
public void onApplicationEvent(ApplicationStartingEvent event) {
if (LIQUIBASE_PRESENT) {
new LiquibasePresent().replaceServiceLocator();
}
}