zoukankan      html  css  js  c++  java
  • Spring Boot 启动事件和监听器,太强大了!

    大家都知道,在 Spring 框架中事件和监听无处不在,打通了 Spring 框架的任督二脉,事件和监听也是 Spring 框架必学的核心知识之一。

    一般来说,我们很少会使用到应用程序事件,但我们也不要忘了它们的存在,比如说在 Spring 框架内部都使用了各种不同的事件来处理不同的任务。

    毫无疑问,在 Spring Boot 框架中,事件和监听也得到了发扬光大,除了常用的 Spring Framework 事件(例如:ContextRefreshedEvent)之外,Spring Boot 在启动过程中还发送一系列其他的应用程序事件。

    Spring Boot 启动事件顺序

    1、ApplicationStartingEvent

    这个事件在 Spring Boot 应用运行开始时,且进行任何处理之前发送(除了监听器和初始化器注册之外)。

    2、ApplicationEnvironmentPreparedEvent

    这个事件在当已知要在上下文中使用 Spring 环境(Environment)时,在 Spring 上下文(context)创建之前发送。

    3、ApplicationContextInitializedEvent

    这个事件在当 Spring 应用上下文(ApplicationContext)准备好了,并且应用初始化器(ApplicationContextInitializers)已经被调用,在 bean 的定义(bean definitions)被加载之前发送。

    4、ApplicationPreparedEvent

    这个事件是在 Spring 上下文(context)刷新之前,且在 bean 的定义(bean definitions)被加载之后发送。

    5、ApplicationStartedEvent

    这个事件是在 Spring 上下文(context)刷新之后,且在 application/ command-line runners 被调用之前发送。

    6、AvailabilityChangeEvent

    这个事件紧随上个事件之后发送,状态:ReadinessState.CORRECT,表示应用已处于活动状态。

    7、ApplicationReadyEvent

    这个事件在任何 application/ command-line runners 调用之后发送。

    8、AvailabilityChangeEvent

    这个事件紧随上个事件之后发送,状态:ReadinessState.ACCEPTING_TRAFFIC,表示应用可以开始准备接收请求了。

    9、ApplicationFailedEvent

    这个事件在应用启动异常时进行发送。


    上面所介绍的这些事件列表仅包括绑定到 SpringApplication 的 SpringApplicationEvents 事件,除了这些事件以外,以下事件也会在 ApplicationPreparedEvent 之后和 ApplicationStartedEvent 之前发送:

    • WebServerInitializedEvent

      这个 Web 服务器初始化事件在 WebServer 启动之后发送,对应的还有 ServletWebServerInitializedEvent(Servlet Web 服务器初始化事件)、ReactiveWebServerInitializedEvent(响应式 Web 服务器初始化事件)。

    • ContextRefreshedEvent

      这个上下文刷新事件是在 Spring 应用上下文(ApplicationContext)刷新之后发送。


    自定义启动事件监听器

    既然我们知道了 Spring Boot 在启动过程中的各个事件,那么我们就可以在每个环节来处理一些我们想做的事情,只需要自定义一个监听器来监听某个事件就可以了。

    比如我们想在上面的第 8 步,即应用启动完成可以接收请求了,我们简单输出一个成功标识。

    Spring Boot 基础的构建这里就不介绍了,如果你对 Spring Boot 还不是很熟悉,或者只是会简单的使用,那还是建议你深入学习下吧,推荐这个 Spring Boot 学习仓库,欢迎 Star 关注:

    https://github.com/javastacks/spring-boot-best-practice

    1、新建监听器

    import lombok.extern.slf4j.Slf4j;
    import org.springframework.boot.availability.AvailabilityChangeEvent;
    import org.springframework.boot.availability.ReadinessState;
    import org.springframework.context.ApplicationListener;
    
    /**
     * 来源微信公众号:Java技术栈
     */
    @Slf4j
    public class JavastackListener implements ApplicationListener<AvailabilityChangeEvent> {
    
        @Override
        public void onApplicationEvent(AvailabilityChangeEvent event) {
            log.info("监听到事件:" + event);
            if (ReadinessState.ACCEPTING_TRAFFIC == event.getState()){
                log.info("应用启动完成,可以请求了……");
            }
        }
    
    }
    

    新建一个自定义监听器,实现了 ApplicationListener 接口,泛型 AvailabilityChangeEvent 表示仅仅监听 AvailabilityChangeEvent 事件。

    因第 8 步的事件和第 6 步的事件同名,我们可以根据事件的状态来区分到底是哪一个环节的事件 。

    2、注册监听器

    注册监听器有两种方式:

    1、在资源目录中的 META-INF/spring.factories 文件中自动注册:

    org.springframework.context.ApplicationListener=
    cn.javastack.springboot.features.listener.JavastackListener
    

    2、如果是监听 Spring 应用上下文(ApplicationContext)创建之后的事件,可以直接在监听器上使用 @Component 注解即可,否则需要使用第一种方法的自动注册,因为 ApplicationContext 并未创建,这时的 Bean 是不能被加载的。

    3、应用启动

    下面来看下启动日志:

    可以看到同时输出了第 6 步和 8 步的监听日志,但只输出第 8 步的启动完成日志,自定义监听实现成功。

    总结

    了解了 Spring Boot 启动过程中的各个事件及监听机制,大家可以依葫芦画瓢实现 Spring Boot 启动过程中的各个自定义操作,比如说在启动过程上实现动态注册、移除 Bean 等。

    一般来说,不建议使用事件和监听器来实现比较耗时和繁重的任务,这样会影响应用程序的正常启动,考虑使用 Spring Boot 的 application/ command-line runners 来进行实现。

    本文只是介绍了一下 Spring Boot 启动过程中的事件及如何实现自定义监听器,怎么实现一个业务上的自定义事件和监听器不在本文范围之类,后续栈长再开一篇,关注公众号Java技术栈第一时间推送,不要走开。

    本文实践所有源代码已上传:

    https://github.com/javastacks/spring-boot-best-practice

    参考资料:

    https://docs.spring.io/spring-boot/docs/2.3.5.RELEASE/reference/htmlsingle/#boot-features-application-events-and-listeners

    最后,觉得有收获,在看、转发一下哦,原创不易,需要鼓励。

    版权申明:本文系公众号 "Java技术栈" 原创,原创实属不易,转载、引用本文内容请注明出处,禁止抄袭、洗稿,请自重,尊重他人劳动成果和知识产权。

    近期热文推荐:

    1.Java 15 正式发布, 14 个新特性,刷新你的认知!!

    2.终于靠开源项目弄到 IntelliJ IDEA 激活码了,真香!

    3.我用 Java 8 写了一段逻辑,同事直呼看不懂,你试试看。。

    4.吊打 Tomcat ,Undertow 性能很炸!!

    5.《Java开发手册(嵩山版)》最新发布,速速下载!

    觉得不错,别忘了随手点赞+转发哦!

  • 相关阅读:
    求助:多个参数的存储过程
    经典回顾:哲学家进餐问题(The Dinning Philosophers Problem)
    杨辉三角
    开发公共课选修系统之二
    关于即时消息系统
    用户 'NT AUTHORITY/NETWORK SERVICE' 登录失败 的解决方法(转)
    细说反射API
    东莞哪家公司可以提供实习的机会?
    使用Gmail发送email时出现Must issue a STARTTLS command first错误!!
    Revolution
  • 原文地址:https://www.cnblogs.com/javastack/p/14138193.html
Copyright © 2011-2022 走看看