Spring Boot事件

一、价值

Spring Boot和Spring 事件是SpringApplication整个生命周期重要环节

二、Spring Boot事件发布

1.切入点

Spring Boot和Spring 事件的触发发生在SpringApplication运行阶段,围绕run(String…)方法不同阶段触发。run(String…)结合SpringApplication初始化阶段完成的相关状态,进一步完善了运行时所需要准备的资源,随后启动Spring应用上下文,在此期间就会伴随Spring Boot和Spring 事件的触发

2. 源码(SpringBoot 2.0和1.0有一定的差别但不大,截图为2.0源码):

在这里插入图片描述
在这里插入图片描述

3.SpringApplicationRunListeners:

按照源码逻辑的实现,SpringApplicationRunListeners是有getRunListeners(String[] args)方法创建的,SpringApplicationRunListeners属于组合模式的实现,重点在其内部关联SpringApplicationRunListener集合
在这里插入图片描述

5.SpringApplicationRunListener:

SpringApplicationRunListener为Spring Boot应用运行时监听器,其监听方法被SpringApplicationRunListeners迭代执行。
监听方法有:

监听方法 运行时阶段说明 事件
starting() Spring应用刚启动 ApplicationStartingEvent
environmentPrepared(ConfigurableEnvironment) ConfigurableEnvironment准备妥当,允许将其调整 ApplicationEnvironmentPreparedEvent
contextPrepared(ConfigurableApplicationContext) ConfigurableApplicationContext准备妥当,允许将其调整
contextLoaded(ConfigurableApplicationContext) ConfigurableApplicationContext已装载,但未启动 ApplicationPreparedEvent
started(ConfigurableApplicationContext) ConfigurableApplicationContext已启动,此时Spring Bean已初始化完成 ApplicationStartedEvent
running(ConfigurableApplicationContext ) Spring应用正在运行 ApplicationReadyEvent
failed(ConfigurableApplicationContext context, Throwable exception) Spring应用运行失败 ApplicationFailedEvent
4.SpringApplicationRunListener内建实现
  1. 结合SpringFactoriesLoader机制,能快速定位到其内建实现:EventPublishingRunListener,而且是唯一实现
    在这里插入图片描述
    在这里插入图片描述
  2. 将SpringApplication初始化阶段关联的ApplicationListener实例列表动态的添加到SimpleApplicationEventMulticaster对象中。SimpleApplicationEventMulticaster源于Spring Framework,从源码可以看出实现ApplicationEventMulticaster接口,用于发布Spring应用事件(ApplicationEvent)。因此EventPublishingRunListener实际是作为Spring Boot事件发布者在这里插入图片描述

四、Spring 事件发布

  1. ApplicationEventMulticaster注册ApplicationListener UML如下:
    在这里插入图片描述
    本质上就是将ApplicationEvent与ApplicationListener集合进行关联,因此AbstractApplicationEventMulticaster#getApplicationListeners(
    ApplicationEvent event, ResolvableType eventType)方法返回event关联ApplicationListener集合。具体可查看源码

  2. ApplicationEventMulticaster事件广播
    主要涉及两个方法:multicastEvent(ApplicationEvent event)和multicastEvent(final ApplicationEvent event, @Nullable ResolvableType eventType),两个这方法均在SimpleApplicationEventMulticaster中实现并且是唯一实现。

  3. ApplicationContext事件发布
    在这里插入图片描述
    从uml文件可以看出ApplicationContext的子接口ConfigurableApplicationContext提供了添加ApplicationListenner实例方法:addApplicationListener(ApplicationListener<?> listener).
    故ApplicationContext通过调用publishEvent(ApplicationEvent event)发布事件

  4. Spring 内建事件

事件 介绍 描述
ContextRefreshedEvent Spring应用上下文就绪事件 当ConfigurableApplicationContext#refresh()方法执行到finishRefresh()方法时,发布ContextRefreshedEvent。此时Spring应用上下文中bean均已完成初始化,可以通过监听该事件获取需要Bean,防止出现Bean提早初始化所带来的的风险
ContextStartedEvent Spring应用上下文启动事件(大多数场景基本不会触发) AbstractApplicationContext#start()时触发,同时能回调Lifecycle Bean的生命周期
ContextStoppedEvent Spring应用上下文停止事件(大多数场景基本不会触发) AbstractApplicationContext#stop()时触发,同时能回调Lifecycle Bean的生命周期
ContextClosedEvent Spring应用上下文关闭事件 ConfigurableApplicationContext#close()时触发,由子类AbstractApplicationContext实现,执行close()后当前Spring应用上下文完全被销毁,无法恢复(这和调用stop()有本质的区别)

5.Spring应用上下文事件ApplicationContextEvent和Spring 内建时间关系如下:
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述在这里插入图片描述

六、run(String…)执行过程中各事件发布点以及顺序(Spring Boot 2.0.8)

序号 监听方法 运行时阶段说明 事件
1 starting() Spring应用刚启动 ApplicationStartingEvent
2 environmentPrepared(ConfigurableEnvironment) ConfigurableEnvironment准备妥当,允许将其调整 ApplicationEnvironmentPreparedEvent
3 prepareContext(…)->contextPrepared(ConfigurableApplicationContext) ConfigurableApplicationContext准备与装载
4 contextLoaded(ConfigurableApplicationContext) ConfigurableApplicationContext已装载,但未启动 ApplicationPreparedEvent
5 refreshContext(context)->AbstractApplicationContext#rrefresh(ApplicationContext)->finishRefresh() ConfigurableApplicationContext启动以及Spring Bean初始化,执行完毕后,Spring应用上下文正式进入Spring生命周期,Spring Boot核心特性也随之启动例如组件自动装配、嵌入式容器启动、Production-Ready特性 ContextRefreshedEvent
6 started(ConfigurableApplicationContext) ConfigurableApplicationContext已启动,此时Spring Bean已初始化完成 ApplicationStartedEvent
7 running(ConfigurableApplicationContext ) Spring应用正在运行 ApplicationReadyEvent
8 failed(ConfigurableApplicationContext context, Throwable exception) Spring应用运行失败 ApplicationFailedEvent

代码验证(Spring Boot 2.0.8)

public static void main(String[] args) {
        new SpringApplicationBuilder(Object.class)
            .listeners(event ->
                System.out.printf("监听到事件: %s , 事件源 : %s\n"
                    , event.getClass().getSimpleName(), event.getSource())
            )
                .web(false)
                .run(args)
                .close();
    }

结果:(注意Spring Boot和Spring 事件源)
在这里插入图片描述

发布了6 篇原创文章 · 获赞 9 · 访问量 379

猜你喜欢

转载自blog.csdn.net/weixin_44397870/article/details/104184638