从监听器到事件
SpringApplication
运行中触发事件,多播器发送事件到监听器,监听器处理事件。
SpingApplication
中事件都是经过SpringApplicationRunListeners
类传送到各个监听器。
以starting事件为例
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<SpringApplicationRunListener> listenerAction,
Consumer<StartupStep> stepAction) {
StartupStep step = this.applicationStartup.start(stepName);
this.listeners.forEach(listenerAction);
if (stepAction != null) {
stepAction.accept(step);
}
step.end();
}
这里的this.listeners
是一个SpringApplicationRunListener
的集合,而SpringApplicationRunListener
的实现类配置中只有一个EventPublishingRunListener
starting事件执行的是EventPublishingRunListener
的starting
方法
public void starting(ConfigurableBootstrapContext bootstrapContext) {
this.initialMulticaster
.multicastEvent(new ApplicationStartingEvent(bootstrapContext, this.application, this.args));
}
这里就找到了第一个事件ApplicationStartingEvent
接着往下执行
public void multicastEvent(ApplicationEvent event) {
multicastEvent(event, resolveDefaultEventType(event));
}
@Override
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);
}
}
}
ResolvableType
类这里略过,里面涉及的内容较多,在这里的具体作用是从类的注解、泛型、继承结构、代理上获取原始的目标对象。
这里要注意的方法getApplicationListeners
,根据事件类型获取监听器,然后执行。
查找的过程比较长,这里列举一些比较重要的方法
类AbstractApplicationEventMulticaster
的getApplicationListeners
、retrieveApplicationListeners
、supportsEvent
。
supportsEvent
方法中有具体的判断逻辑
protected boolean supportsEvent(
ApplicationListener<?> listener, ResolvableType eventType, @Nullable Class<?> sourceType) {
GenericApplicationListener smartListener = (listener instanceof GenericApplicationListener ?
(GenericApplicationListener) listener : new GenericApplicationListenerAdapter(listener));
return (smartListener.supportsEventType(eventType) && smartListener.supportsSourceType(sourceType));
}
根据监听器的类型调用监听器类的支持事件类型supportsEventType
和支持事件源类型supportsSourceType
两个方法,来判断是否传播到该监听器。
ApplicationListener
监听器有多个实现。
ClearCachesApplicationListener
ParentContextCloserApplicationListener
FileEncodingApplicationListener
AnsiOutputApplicationListener
DelegatingApplicationListener
LoggingApplicationListener
EnvironmentPostProcessorApplicationListener
BackgroundPreinitializer
ClearCachesApplicationListener
结构:
implements ApplicationListener<ContextRefreshedEvent>
支持的事件类型:
ContextRefreshedEvent
ApplicationContextEvent
支持的事件源:
无限制
ParentContextCloserApplicationListener
结构:
implements ApplicationListener<ParentContextAvailableEvent>, ApplicationContextAware, Ordered
支持的事件类型
ParentContextAvailableEvent
支持的事件源:
无限制
FileEncodingApplicationListener
结构:
implements ApplicationListener<ApplicationEnvironmentPreparedEvent>, Ordered
支持的事件类型:
ApplicationEnvironmentPreparedEvent
支持的事件源:
无限制
AnsiOutputApplicationListener
结构:
implements ApplicationListener<ApplicationEnvironmentPreparedEvent>, Ordered
支持的事件类型:
ApplicationEnvironmentPreparedEvent
支持的事件源:
无限制
DelegatingApplicationListener
结构:
implements ApplicationListener<ApplicationEvent>, Ordered
支持的事件类型:
ApplicationEvent
及其子类
支持的事件源:
无限制
LoggingApplicationListener
结构:
implements GenericApplicationListener
支持的事件类型:
ApplicationStartingEvent
ApplicationEnvironmentPreparedEvent
ApplicationPreparedEvent
ContextClosedEvent
ApplicationFailedEvent
支持的事件源:
SpringApplication
ApplicationContext
EnvironmentPostProcessorApplicationListener
结构:
implements SmartApplicationListener, Ordered
支持的事件类型:
ApplicationEnvironmentPreparedEvent
ApplicationPreparedEvent
ApplicationFailedEvent
支持的事件源:
SpringApplication
ApplicationContext
BackgroundPreinitializer
结构:
implements ApplicationListener<SpringApplicationEvent>
支持的事件类型:
SpringApplicationEvent
及其子类
支持的事件源:
无限制
事件
从EventPublishingRunListener
的方法还有上面的事件类型,SpringBoot中的事件类型有:
ApplicationStartingEvent
ApplicationEnvironmentPreparedEvent
ApplicationContextInitializedEvent
ApplicationPreparedEvent
ApplicationStartedEvent
ApplicationReadyEvent
除了multicastEvent
多播事件,还有下面两个方法发布事件。
@Override
public void started(ConfigurableApplicationContext context, Duration timeTaken) {
context.publishEvent(new ApplicationStartedEvent(this.application, this.args, context, timeTaken));
AvailabilityChangeEvent.publish(context, LivenessState.CORRECT);
}
@Override
public void ready(ConfigurableApplicationContext context, Duration timeTaken) {
context.publishEvent(new ApplicationReadyEvent(this.application, this.args, context, timeTaken));
AvailabilityChangeEvent.publish(context, ReadinessState.ACCEPTING_TRAFFIC);
}
事实上,这些事件都在一个包路径下。
ApplicationStartingEvent
注释:
事件在启动SpringApplication后尽早发布——在Environment或ApplicationContext可用之前,但在ApplicationListeners注册之后。事件的来源是SpringApplication本身,但要注意在早期阶段不要过多地使用其内部状态,因为它可能会在生命周期的后期被修改。
使用的翻译,不甚明了,得看看怎么这个事件触发后,监听器做了什么。
ApplicationEnvironmentPreparedEvent
注释:
当SpringApplication启动并且环境首次可用于检查和修改时发布的事件
ApplicationContextInitializedEvent
注释:
在启动SpringApplication、准备ApplicationContext和调用ApplicationContextInitializer时发布的事件,但在加载任何bean定义之前。
ApplicationPreparedEvent
注释:
当SpringApplication正在启动并且ApplicationContext已完全准备好但未刷新时发布的事件。将加载bean定义,并且环境已准备好在此阶段使用
ApplicationStartedEvent
注释:
刷新应用程序上下文后,但在调用任何应用程序和命令行运行程序之前发布的事件
ApplicationReadyEvent
注释:
事件尽可能晚地发布,以指示应用程序已准备好为请求提供服务。事件的来源是SpringApplication本身,但要注意修改其内部状态,因为届时所有初始化步骤都已完成
ApplicationFailedEvent
注释:
SpringApplication在启动失败时发布的事件