SpringBoot启动分析2:SpringApplicationRunListeners初始化

当SpringApplication初始化完毕后,就开始调用实际的run方法执行其他初始了:

SpringApplicationRunListeners listeners = getRunListeners(args);
listeners.starting();

需要注意的是这里的监听器和SpringApplication中的监听器不一样,前者是SpringApplicationRunListeners类型而后者是ApplicationListener类型。
点击getRunListeners方法进入查看对应的源码:

private SpringApplicationRunListeners getRunListeners(String[] args) {
	Class<?>[] types = new Class<?>[] { SpringApplication.class, String[].class };
	return new SpringApplicationRunListeners(logger,
			getSpringFactoriesInstances(SpringApplicationRunListener.class, types, this, args));
}

可以看出依然是调用通用的方法getSpringFactoriesInstances来获取配置上的信息,需要注意的是除了类型参数(根据实际类型读取配置上的实现),还包含已经初始化好的SpringApplication和String类。
EventPublishingRunListener是SpringApplicationRunListeners接口的实现类,这里读取出来的配置就是该类,该类用于发布SpringApplicationEvent类型的事件。
当getSpringFactoriesInstances方法读取到EventPublishingRunListener信息后需要调用createSpringFactoriesInstances方法将其实例化,在实例化过程中会涉及以下初始化工作:

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

可以看出初始化SpringApplication时所实例化的所有ApplicationListener类型的监听器都加入到该广播中,为了后续使用SpringApplicationRunListeners启动这些监听器做了初始化。
当SpringApplicationRunListeners启动时,通过EventPublishingRunListener调用实际的启动方法:
SpringBoot启动分析2:SpringApplicationRunListeners初始化
这时的启动逻辑就全权交由给EventPublishingRunListener来处理了:

public class EventPublishingRunListener implements SpringApplicationRunListener, Ordered {
	......
	@Override
	public void starting() {
		this.initialMulticaster.multicastEvent(new ApplicationStartingEvent(this.application, this.args));
	}
	......
}	

每个Listener都会间接或直接实现ApplicationListener,所以都需要重写onApplicationEvent方法,而EventPublishingRunListener就是通过遍历的方式获取每一个从spring.factories文件中读取并实例化的监听器,并调用这些监听器的onApplicationEvent方法:

public void multicastEvent(ApplicationEvent event, @Nullable ResolvableType eventType) {
	ResolvableType type = eventType != null ? eventType : this.resolveDefaultEventType(event);
	Executor executor = this.getTaskExecutor();
	// 获取到所有监听器
	Iterator var5 = this.getApplicationListeners(event, type).iterator();
	// 遍历监听器并调用每个监听器的onApplicationEvent方法
	while(var5.hasNext()) {
		ApplicationListener<?> listener = (ApplicationListener)var5.next();
		if (executor != null) {
			executor.execute(() -> {
				this.invokeListener(listener, event);
			});
		} else {
			this.invokeListener(listener, event);
		}
	}
}
protected void invokeListener(ApplicationListener<?> listener, ApplicationEvent event) {
	ErrorHandler errorHandler = this.getErrorHandler();
	if (errorHandler != null) {
		try {
			this.doInvokeListener(listener, event);
		} catch (Throwable var5) {
			errorHandler.handleError(var5);
		}
	} else {
		this.doInvokeListener(listener, event);
	}
}
private void doInvokeListener(ApplicationListener listener, ApplicationEvent event) {
	try {
		// 监听器实例调用本身的onApplicationEvent方法
		listener.onApplicationEvent(event);
	} catch (ClassCastException var6) {
		String msg = var6.getMessage();
		if (msg != null && !this.matchesClassCastMessage(msg, event.getClass())) {
			throw var6;
		}
		Log logger = LogFactory.getLog(this.getClass());
		if (logger.isTraceEnabled()) {
			logger.trace("Non-matching event type for listener: " + listener, var6);
		}
	}
}

这里不再描述每个监听器实际的onApplicationEvent方法执行流程,等后续有涉及说明。
备注:对于自定义监听器,在通过applicationContext.publishEvent(event)发布之后,其中的逻辑也是走的上方这一套:

protected void publishEvent(Object event, @Nullable ResolvableType eventType) {
	Assert.notNull(event, "Event must not be null");
	Object applicationEvent;
	if (event instanceof ApplicationEvent) {
		applicationEvent = (ApplicationEvent)event;
	} else {
		applicationEvent = new PayloadApplicationEvent(this, event);
		if (eventType == null) {
			eventType = ((PayloadApplicationEvent)applicationEvent).getResolvableType();
		}
	}
	if (this.earlyApplicationEvents != null) {
		this.earlyApplicationEvents.add(applicationEvent);
	} else {
		// 实际也是获取ApplicationEventMulticaster的实现类SimpleApplicationEventMulticaster再通过multicastEvent方法广播出去。
		this.getApplicationEventMulticaster().multicastEvent((ApplicationEvent)applicationEvent, eventType);
	}
	if (this.parent != null) {
	        if (this.parent instanceof AbstractApplicationContext) {
			((AbstractApplicationContext)this.parent).publishEvent(event, eventType);
		} else {
			this.parent.publishEvent(event);
		}
	}
}

SpringBoot启动分析2:SpringApplicationRunListeners初始化

上一篇:create-react-app中的babel配置探索


下一篇:CCNA - Part8 - Cisco IOS Switch, Router 基础配置