Spring Boot 同步消息机制

545 阅读4分钟

SpringApplicationRunListeners

SpringApplicationRunListeners 是一个类属性为

private final Log log; //记录日志

private final List<SpringApplicationRunListener> listeners; //SpringApplicationRunListener列表

SpringApplicationRunListener

SpringApplicationRunListener 是接口,规定了一些动作。

类比

将整个事件机制比作一个大公司。
那么SpringApplicationRunListeners就是CEO,大事,大流程都是CEO做主。那么SpringApplicationRunListener就是一组能力,拥有这组能力的人都可以被任命为经理级别,归CEO管理。
在Spring Boot中就有一个叫EventPublishingRunListener人,他就有这么一些能力,所以他就做为了目前为止的唯一一位经理。
但是光有CEO和经理是没用的,必须要有业务人员才能真正让事情得以实现。
于是我们干活的人员都登场了:

org.springframework.boot.ClearCachesApplicationListener,\
org.springframework.boot.builder.ParentContextCloserApplicationListener,\
org.springframework.boot.cloud.CloudFoundryVcapEnvironmentPostProcessor,\
org.springframework.boot.context.FileEncodingApplicationListener,\
org.springframework.boot.context.config.AnsiOutputApplicationListener,\
org.springframework.boot.context.config.ConfigFileApplicationListener,\
org.springframework.boot.context.config.DelegatingApplicationListener,\
org.springframework.boot.context.logging.ClasspathLoggingApplicationListener,\
org.springframework.boot.context.logging.LoggingApplicationListener,\
org.springframework.boot.liquibase.LiquibaseServiceLocatorApplicationListener

干活的人各有各的岗位,各有各的活,暂不一一介绍。
但是他们都必须具备同样一项业务能力,那就是ApplicationListener,这个能力要求大家都实现onApplicationEvent方法,这样大家接收来自经理(EventPublishingRunListener)的命令。

开始干活

有了上面3个级别的人大家就可以开始干活了。
CEO 先给所有经理下命令说开始干活,当然这个时候只有一个``EventPublishingRunListener经理,那么经理接收到开始干活的命令,他就要把这个开始干活的命令传达到下面的业务人员。那么经理使用的是群发的形式,而实现群发能力的工具叫做SimpleApplicationEventMulticaster。
SimpleApplicationEventMulticaster 最终通过onApplicationEvent的方式去告知业务人员要开始干活了。

了解SpringApplicationRunListeners(CEO)的职责。

在Spring Boot 中CEO 干好下面几件事就好:

	void starting() { //开始做准备工作
	}
	void environmentPrepared(ConfigurableEnvironment environment) { //环境准备结束
	}
	void contextPrepared(ConfigurableApplicationContext context) { //上下文准备结束
	}
	void contextLoaded(ConfigurableApplicationContext context) { //上下文加载完成
	}
	void started(ConfigurableApplicationContext context) { //准备工作结束
	}
	void running(ConfigurableApplicationContext context) { //准备工作完成开始运作
	}
	void failed(ConfigurableApplicationContext context, Throwable exception) { //工作失败出错
	}

CEO只会下上面几个命令。这个CEO是不是很好当。
既然CEO只会上面几个命令,那么经理也只要能应对上面几个命令就好了,所以CEO在招聘经理的时候就是按照上面几个命令提出一直要求(SpringApplicationRunListener)注意有s和没s区别很大。对于每个功能的描述英文其实写得挺清楚,我这里就给翻译翻译。

public interface SpringApplicationRunListener {

	/**
	 * Called immediately when the run method has first started. Can be used for very
	 * early initialization.
	 */
    //当应用第一次调用run方法时,在初始化之前被调用。
	default void starting() {
	}

	/**
	 * Called once the environment has been prepared, but before the
	 * {@link ApplicationContext} has been created.
	 * @param environment the environment
	 */
    //在环境准备好,但是上下文还没准备好的时候被调用
	default void environmentPrepared(ConfigurableEnvironment environment) {
	}

	/**
	 * Called once the {@link ApplicationContext} has been created and prepared, but
	 * before sources have been loaded.
	 * @param context the application context
	 */
    //上下文准备好,但资源还没加载好之前被调用
	default void contextPrepared(ConfigurableApplicationContext context) {
	}

	/**
	 * Called once the application context has been loaded but before it has been
	 * refreshed.
	 * @param context the application context
	 */
    //上下文更新前被调用
	default void contextLoaded(ConfigurableApplicationContext context) {
	}

	/**
	 * The context has been refreshed and the application has started but
	 * {@link CommandLineRunner CommandLineRunners} and {@link ApplicationRunner
	 * ApplicationRunners} have not been called.
	 * @param context the application context.
	 * @since 2.0.0
	 */
    //上下文更新后被调用
	default void started(ConfigurableApplicationContext context) {
	}

	/**
	 * Called immediately before the run method finishes, when the application context has
	 * been refreshed and all {@link CommandLineRunner CommandLineRunners} and
	 * {@link ApplicationRunner ApplicationRunners} have been called.
	 * @param context the application context.
	 * @since 2.0.0
	 */
    //run方法完成的时候被调用
	default void running(ConfigurableApplicationContext context) {
	}

	/**
	 * Called when a failure occurs when running the application.
	 * @param context the application context or {@code null} if a failure occurred before
	 * the context was created
	 * @param exception the failure
	 * @since 2.0.0
	 */
    //当应用运行时出现问题被调用。
	default void failed(ConfigurableApplicationContext context, Throwable exception) {
	}
}

这一组能力就跟CEO(SpringApplicationRunListeners)的职责是对应的。也就是CEO 聘请经理的标准就是能对这些命令做出响应的人。默认情况下,只有EventPublishingRunListener这一人。

总结:

我这边梳理几个概念希望大家能理解,具体实现大家可以参照代码,知道概念流程后还是很好懂的。

  • SpringApplicationRunListeners  (CEO,从大局管理整个流程)
  • SpringApplicationRunListener (一组能力,拥有这组能力才能应对CEO提出的命令)
  • EventPublishingRunListener (实现了SpringApplicationRunListener 的人)
  • SimpleApplicationEventMulticaster (通知业务员的工具)
  • ApplicationListener(业务员需要具备的通用能力)