springboot中的事件

本文详细解析了SpringBoot中事件的发布顺序与监听机制,包括ApplicationStartingEvent至ApplicationFailedEvent的触发时机,以及如何自定义事件与监听器。通过实例展示了不同监听方式的实现,如@EventListener注解和实现ApplicationListener接口。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

官网对springboot事件的描述

springboot中事件的发布顺序(发送优先级从高到底)

  • ApplicationStartingEvent在运行开始时发送 ,但在进行任何处理之前(侦听器和初始化程序的注册除外)发送
  • ApplicationEnvironmentPreparedEvent当被发送Environment到中已知的上下文中使用,但是在创建上下文之前
  • ApplicationContextInitializedEventApplicationContext准备好且已调用ApplicationContextInitializers之后但任何bean定义未加载之前发送
  • ApplicationPreparedEvent在刷新开始之前但在加载bean定义之后发送
  • ApplicationStartedEvent上下文已被刷新后发送,但是任何应用程序和命令行亚军都被调用前
  • ApplicationReadyEvent在所有的命令行应用启动后发送此事件,可以处理请求

    ps:这里的命令行引用主要是指扩展了ApplicationRunnerCommandLineRunner的实现

  • ApplicationFailedEvent如果在启动时异常发送

自定义扩展事件或监听springboot事件方法

前提:需要等待ApplicationContext已经初始化完成才能通过其发送事件

  • 自定义事件
/**
 * @Author xf
 * @Description 事件(消息)
 * @Date 2019/12/6 16:41
 **/
public class MessageEvent extends ApplicationEvent {
    public MessageEvent(Object source) {
        super(source);
    }
}
  • 自定义监听器
    • 实现方式1:通过@EventListener指定需要监听的事件,常用
      /**
       * @Author xf
       * @Description 事件监听
       * @Date 2019/12/6 16:42
       **/
      @Component
      public class MyListener {
          @EventListener(value = MessageEvent.class)
          public void listener(Object object){
              System.out.println("MyListener  = " + object);
          }
      }
      
    • 实现方式2:通过实现EventListener
      /**
       * @Author xf
       * @Description 刷新事件监听
       * @Date 2019/12/6 17:05
       **/
       @Component
      public class RefreshEventListener implements ApplicationListener {
          @Override
          public void onApplicationEvent(ApplicationEvent applicationEvent) {
              if(applicationEvent instanceof MessageEvent){
                  final MessageEvent messageEvent = (MessageEvent) applicationEvent;
                  System.out.println("(RefreshEventListener ) = " + messageEvent);
              }
          }
      }
      
    • 通过spring.factories方法扩展,这个方法不太合适用在这里,可读性不高,与上一个实现方式的区别就是去掉了注解@Component。放在spring.factories内让spring进行初始化.spring在初始化所有扩展spring.factories的内容时一并初始化。这种方式是自定义spring-boot-starter-xxx.jar的时候常用的方法。
      public class SpringFactoriesEventListener implements ApplicationListener {
          @Override
          public void onApplicationEvent(ApplicationEvent applicationEvent) {
              if(applicationEvent instanceof MessageEvent){
                  final MessageEvent messageEvent = (MessageEvent) applicationEvent;
                  System.out.println("(SpringFactoriesEventListener ) = " + messageEvent);
              }
          }
      }
      
      添加META-INF文件夹,并新建spring.factories文件,添加如下内容
      org.springframework.context.ApplicationListener=com.xfc.transactional.transactional.listener.SpringFactoriesEventListener
      

最后看一下运行结果

  .   ____          _            __ _ _
 /\\ / ___'_ __ _ _(_)_ __  __ _ \ \ \ \
( ( )\___ | '_ | '_| | '_ \/ _` | \ \ \ \
 \\/  ___)| |_)| | | | | || (_| |  ) ) ) )
  '  |____| .__|_| |_|_| |_\__, | / / / /
 =========|_|==============|___/=/_/_/_/
 :: Spring Boot ::        (v2.2.1.RELEASE)

2019-12-06 18:12:36.212  INFO 620792 --- [           main] c.x.t.t.TransactionalApplication         : Starting TransactionalApplication on chenxingfei with PID 620792 (D:\personal-workspace\transactional\target\classes started by mintq in D:\personal-workspace\transactional)
2019-12-06 18:12:36.218  INFO 620792 --- [           main] c.x.t.t.TransactionalApplication         : No active profile set, falling back to default profiles: default
2019-12-06 18:12:39.730  INFO 620792 --- [           main] o.s.b.w.embedded.tomcat.TomcatWebServer  : Tomcat initialized with port(s): 8080 (http)
2019-12-06 18:12:39.759  INFO 620792 --- [           main] o.apache.catalina.core.StandardService   : Starting service [Tomcat]
2019-12-06 18:12:39.760  INFO 620792 --- [           main] org.apache.catalina.core.StandardEngine  : Starting Servlet engine: [Apache Tomcat/9.0.27]
2019-12-06 18:12:39.972  INFO 620792 --- [           main] o.a.c.c.C.[Tomcat].[localhost].[/]       : Initializing Spring embedded WebApplicationContext
2019-12-06 18:12:39.972  INFO 620792 --- [           main] o.s.web.context.ContextLoader            : Root WebApplicationContext: initialization completed in 3484 ms
2019-12-06 18:12:40.987  INFO 620792 --- [           main] o.s.s.concurrent.ThreadPoolTaskExecutor  : Initializing ExecutorService 'applicationTaskExecutor'
2019-12-06 18:12:41.748  INFO 620792 --- [           main] o.s.b.w.embedded.tomcat.TomcatWebServer  : Tomcat started on port(s): 8080 (http) with context path ''
2019-12-06 18:12:41.757  INFO 620792 --- [           main] c.x.t.t.TransactionalApplication         : Started TransactionalApplication in 7.269 seconds (JVM running for 8.432)
(MyListener) = com.xfc.transactional.transactional.event.MessageEvent[source=我发布事件了]
(SpringFactoriesEventListener) = com.xfc.transactional.transactional.event.MessageEvent[source=我发布事件了]
(RefreshEventListener) = com.xfc.transactional.transactional.event.MessageEvent[source=我发布事件了]

欢迎交流哦!!!私信我

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值