SpringBoot源码阅读(4)——事件

从监听器到事件

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事件执行的是EventPublishingRunListenerstarting方法

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,根据事件类型获取监听器,然后执行。
查找的过程比较长,这里列举一些比较重要的方法
AbstractApplicationEventMulticastergetApplicationListenersretrieveApplicationListenerssupportsEvent
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在启动失败时发布的事件

相关推荐

  1. springboot的类阅读顺序

    2024-07-13 08:42:02       40 阅读
  2. SpringBoot阅读(9)——转换服务

    2024-07-13 08:42:02       18 阅读
  3. springboot 事件发布机制浅析】

    2024-07-13 08:42:02       53 阅读
  4. SpringBoot阅读(11)——后处理器2

    2024-07-13 08:42:02       24 阅读
  5. babyAGI(6)-babyCoder阅读4_Embbeding代码实现

    2024-07-13 08:42:02       31 阅读

最近更新

  1. docker php8.1+nginx base 镜像 dockerfile 配置

    2024-07-13 08:42:02       67 阅读
  2. Could not load dynamic library ‘cudart64_100.dll‘

    2024-07-13 08:42:02       72 阅读
  3. 在Django里面运行非项目文件

    2024-07-13 08:42:02       58 阅读
  4. Python语言-面向对象

    2024-07-13 08:42:02       69 阅读

热门阅读

  1. C#往数据库上传文件

    2024-07-13 08:42:02       19 阅读
  2. 数据分包:145字节版本

    2024-07-13 08:42:02       23 阅读
  3. py2neo常用语句

    2024-07-13 08:42:02       26 阅读
  4. gitlab 备份和还原

    2024-07-13 08:42:02       29 阅读
  5. 如何实现一个二叉搜索树

    2024-07-13 08:42:02       27 阅读
  6. 小妙招使用sysctl hw.realmem查看实际物理内存@FreeBSD

    2024-07-13 08:42:02       19 阅读
  7. 网络设备安全

    2024-07-13 08:42:02       23 阅读
  8. sqlalchemy.orm中validates对两个字段进行联合校验

    2024-07-13 08:42:02       27 阅读
  9. Grafana

    Grafana

    2024-07-13 08:42:02      24 阅读
  10. VB 实例:掌握 Visual Basic 编程的精髓

    2024-07-13 08:42:02       21 阅读