【玩转SpringBoot】通过事件机制参与SpringBoot应用的启动过程
生命周期和事件监听
一个应用的启动过程和关闭过程是归属到“生命周期”这个概念的范畴。
典型的设计是在启动和关闭过程中会触发一系列的“事件”,我们只要监听这些事件,就能参与到这个过程中来。
要想监听事件,首先得有事件监听器,就是常说的Listener。下面就是Spring提供的监听器,如下图01:

按规定所有的监听器都要继承Java提供的EventListener接口,这个接口是一个空的marker接口,其实就是标识一下。
事件一般都有多个,一般也有两种常用解决方法:
要么定义多个监听器接口,一个事件一个接口。
要么一个接口里定义多个方法,一个事件一个方法。
可惜的是,这两种方法Spring都没有采用,仍然只用了一个接口一个方法,那它是如何实现的呢?
相信大家已经看到,监听器接口有一个泛型参数,没错,就是根据泛型参数的不同来区分不同事件的。
这个泛型参数就是事件对象,按规定所有的事件对象都要继承Java提供的EventObject类,如下图02:

Java提供这个类除了有标识作用外,还和事件源有关。任何事件都会有一个触发者,它就是事件源。可以认为是事件的起源或来源。
既然所有事件都有,干脆提升到顶级父类里算了。如下图03:

不同的事件,含义完全不同,所以差别很大,因此,通常一种事件会有属于自己的一种事件对象。
我们只需要看下事件对象有多少种,就能知道事件有多少种。这种判断方式一般都没有问题。
下面就是和SpringBoot启动有关的所有事件对象类型,如下图04:

一共有七种事件对象,除去一种是处理失败用的,还剩六种。也就是说我们可以通过六个事件参与到SpringBoot应用的启动中去。
实现事件监听器接口
监听器就是接口,我们首先要实现这些接口,加入处理逻辑。然后把它们添加到应用中去就行了。
有六种事件对象,我们需要定义六个实现类。
事件对象为ApplicationStartingEvent,如下图05:

事件对象为ApplicationEnvironmentPreparedEvent,如下图06:

事件对象为ApplicationContextInitializedEvent,如下图07:

事件对象为ApplicationPreparedEvent,如下图08:

事件对象为ApplicationStartedEvent,如下图09:

事件对象为ApplicationReadyEvent,如下图10:

把这个六个实现类添加到SpringBoot应用中,如下图11:

实现Runner接口
SpringBoot提供了两个Runner接口,如下图1213:


这两个接口主要用于满足那种应用刚启动好后就需要立马被执行的需求。如定时任务。
我们也来实现下这两个接口,如下图1415:


有一点需要注意的是,这两个接口的实现类需要作为bean注册到容器中去。
实现Spring容器初始化接口
如果我们需要对Spring容器进行一些自定义的初始化,可以实现这个接口,如下图16:

这个接口的泛型参数其实就是容器对象。
我们也来实现下这个接口,如下图1718:


我们可以多次实现这个接口,需要排序的话可以使用@Order注解或实现Ordered接口。
然后把这些实现类添加到SpringBoot应用中去,如下图19:

启动应用,观察事件触发的次序
启动后首先触发启动事件,如下图20:

接着要做的就是确认环境,创建Environment,然后触发事件,表明环境已经OK了。如下图21:

然后根据环境创建Spring容器对象,创建好后执行自定义容器初始化,如下图22:

初始化完成后,触发事件,表明容器就已经准备好了,如下图23:

容器OK之后,就会加载资源(主要是注册bean定义),加载完成后,就会触发事件,如下图24:

接着Spring容器就会进行refresh,refresh完成之后,其实Spring容器就已经成功启动好了。
这时会触发事件,如下图25:

容器启动好后,立马就会执行Runner,如下图26:

Runner执行完后,SpringBoot应用就真正启动好了,进入了正常运行状态。
这时会触发最后一个事件,如下图27:

我们可以根据需要,在对应的事件里完成自己的需求。
(END)
>>> 玩转SpringBoot系列文章 <<<
【玩转SpringBoot】用好条件相关注解,开启自动配置之门
【玩转SpringBoot】看似复杂的Environment其实很简单
【玩转SpringBoot】让错误处理重新由web服务器接管
【玩转SpringBoot】SpringBoot应用的启动过程一览表
>>> 品Spring系列文章 <<<
品Spring:SpringBoot和Spring到底有没有本质的不同?
品Spring:SpringBoot轻松取胜bean定义注册的“第一阶段”
品Spring:SpringBoot发起bean定义注册的“二次攻坚战”
品Spring:注解之王@Configuration和它的一众“小弟们”
品Spring:对@PostConstruct和@PreDestroy注解的处理方法
品Spring:对@Autowired和@Value注解的处理方法
品Spring:真没想到,三十步才能完成一个bean实例的创建
品Spring:关于@Scheduled定时任务的思考与探索,结果尴尬了
>>> 热门文章集锦 <<<
爸爸又给Spring MVC生了个弟弟叫Spring WebFlux
【面试】吃透了这些Redis知识点,面试官一定觉得你很NB(干货 | 建议珍藏)
【面试】如果你这样回答“什么是线程安全”,面试官都会对你刮目相看(建议珍藏)
【面试】迄今为止把同步/异步/阻塞/非阻塞/BIO/NIO/AIO讲的这么清楚的好文章(快快珍藏)
【面试】一篇文章帮你彻底搞清楚“I/O多路复用”和“异步I/O”的前世今生(深度好文,建议珍藏)
作者是工作超过10年的码农,现在任架构师。喜欢研究技术,崇尚简单快乐。追求以通俗易懂的语言解说技术,希望所有的读者都能看懂并记住。下面是公众号的二维码,欢迎关注!

【玩转SpringBoot】通过事件机制参与SpringBoot应用的启动过程的更多相关文章
- springBoot的事件机制---GenericApplicationListener用法
springBoot的事件机制---GenericApplicationListener用法 什么是ApplicationContext? 它是Spring的核心,Context我们通常解释为上下文环 ...
- Android系统进程间通信(IPC)机制Binder中的Server启动过程源代码分析
文章转载至CSDN社区罗升阳的安卓之旅,原文地址:http://blog.csdn.net/luoshengyang/article/details/6629298 在前面一篇文章浅谈Android系 ...
- Android系统Surface机制的SurfaceFlinger服务的启动过程分析
文章转载至CSDN社区罗升阳的安卓之旅,原文地址:http://blog.csdn.net/luoshengyang/article/details/8022957 在前面一篇文章中,我们简要介绍了A ...
- [译]谈谈SpringBoot 事件机制
要"监听"事件,我们总是可以将"监听器"作为事件源中的另一个方法写入事件,但这将使事件源与监听器的逻辑紧密耦合. 对于实际事件,我们比直接方法调用更灵活.我们可 ...
- SpringBoot内置生命周期事件详解 SpringBoot源码(十)
SpringBoot中文注释项目Github地址: https://github.com/yuanmabiji/spring-boot-2.1.0.RELEASE 本篇接 SpringBoot事件监听 ...
- 深入springboot原理——一步步分析springboot启动机制(starter机制)
前言 使用过springboot的同学应该已经知道,springboot通过默认配置了很多框架的使用方式帮我们大大简化了项目初始搭建以及开发过程.本文的目的就是一步步分析springboot的启动过程 ...
- 【玩转SpringBoot】SpringBoot应用的启动过程一览表
SpringBoot应用的启动方式很简单,就一行代码,如下图01: 其实这行代码背后主要执行两个方法,一个是构造方法,一个是run方法. 构造方法主要内容就是收集一些数据,和确认一些信息.如下图02: ...
- SpringBoot系列——事件发布与监听
前言 日常开发中,我们经常会碰到这样的业务场景:用户注册,注册成功后需要发送邮箱.短信提示用户,通常我们都是这样写: /** * 用户注册 */ @GetMapping("/userRegi ...
- ApplicationEvent事件机制源码分析
<spring扩展点之三:Spring 的监听事件 ApplicationListener 和 ApplicationEvent 用法,在spring启动后做些事情> <服务网关zu ...
随机推荐
- CSS层叠样式表的层叠是什么意思
层叠的意思就是“继承”.“权重”.“覆盖”,通过良好的层级命名更好的实现效果,更少的代码,更多的功能,下面为大家详细介绍下,感兴趣的朋友不要错过 解答一: 层叠指的是样式的优先级,当产生冲突时以优 ...
- Maven exclusions(排除依赖)
在写pom的时候,我们写的一个依赖往往会依赖于其他的包,而这些包可能是过时的不安全的,因此需要排除并重新引用安全的版本,先在依赖这个项目的pom中去除想排除的依赖,再添加指定版本的依赖. pom的依赖 ...
- charles修改请求体内容
charles修改请求体内容 问:什么是请求体?答:客户端向服务端发出的请求简称请求体,请求体中包含有许许多多的参数,每一个参数都有其特定的意义.多一个或者少一个则服务端给你返回的响应体就会不一样 一 ...
- k8s 管理机密信息
一.启动应用安全信息的保护: Secret介绍: 应用启动过程中可能需要一些敏感信息,比如访问数据库的用户名密码或者秘钥.将这些信息直接保存在容器镜像中显然不妥,Kubernetes 提供的解决方案是 ...
- 【笔记】Docker部署Odoo
一,制作一个自己的odoo镜像odoo:yto 1,下载一个odoo10的镜像 docker pull odoo:10.0 2,按照自己的意愿修改里面的内容 docker run -it -u roo ...
- java-创建对象实例
1.A a = new A(); 2.Class class = B.Class; B b = class .newInstance();
- C# 关于App.config
App.config是winfrom等程序的应用程序配置文件,用来存放一些参数. app.config只会在应用程序启动时加载一次. 当程序在运行中修改app.config中的参数是不会生效,必须要重 ...
- 安装多个版本的TensorFlow
TensorFlow 2.0测试版在今年春季发布,新版本比1.x版本在易用性上有了很大的提升.但是由于2.0发布还没有多久,现在大部分论文的实现代码都是1.x版本的,所以在学习TensorFlow的过 ...
- Python Network Security Programming-1
UNIX口令破解1.程序运行需求: 其中dictionary.txt文件为破解口令的字典文件,passwords.txt文件为临时存放UNIX系统密码的文件 2.程序源码: import crypt ...
- 使用PowerShell 自动安装IIS 及自动部署网站
执行环境:Windows Server 2012 R2 安装iis核心代码,可自定义安装项 注意这里不能使用add-windowsfeature "Web-Filtering", ...