Spring Boot的Listener机制的用法和实现原理详解

之前在介绍了在spring-boot启动过程中调用runner的原理,今天我们介绍另外一种可以实现相似功能的机制:spring-boot的Listener机制。

通过注册Listener,可以实现对于spring-boot整个生命周期各个状态变化进行监听,然后执行相应的业务代码。我们只需要监听其中几个启动状态就能够实现runner一样的功能了。

如何使用Spring Boot Listener

要想在spring-boot工程中加入自己实现的Listener,只需要完成一下两步动作:

  1. 实现SpringApplicationRunListener接口
  2. 在spring.factories文件中添加上相应的配置

样例代码:

SpringApplicationRunListener实现

spring.factories中的配置

运行结果:

从运行结果我们可以看出:

  • 各个状态回调的顺序为:starting->environmentPrepared->contextPrepared->contextLoaded->started->running,再加上一个启动出错时的回调failed
  • 每一个状态的回调对应的是spring-boot程序在启动时的不同的阶段,可以利用的spring-boot资源也是不一样的,比如starting状态就无法利用任何spring-boot相关的功能,因为这个时候spring-boot还没有进行任何实际的初始化。

Spring Boot Listener的实现原理

Listener的原理可以总结为:

  1. 加载SpringApplicationRunListener接口的实现类
  2. 在spring-boot各个启动阶段调用相应的Listener接口

首先我们来看看SpringApplicationRunListener接口的实现类是怎么被加载起来的。要向了解Listener是如何被加载的,就需要先知道Spring的SPI机制(spring.factories机制),这个我将会在另外一篇文章中介绍。

进入SpringApplication的run方法,我们可以看到如下的一段代码:

加载Listener

在这里就是调用了加载Listener的方法,最终会走到如下的代码中去

在这个方法中主要做了三件事情:

  • 利用spring.factories的机制获取了所有SpringApplicationRunListener实现类的类名。
  • 根据查找到的类名进行实例化,使用的是带有SpringApplication和String[]两个参数的构造方法。
  • 这些SpringApplicationRunListener实例按照order进行排序。

接下来我们再看看Listener是如何被调用的。

调用starting

 在Listener被加载完成以后就立马调用starting方法了,这个时候spring-boot实际什么都没有初始化,所以无法使用任何的spring-boot特性。

调用environmentPrepared

 调用environmentPrepared

调用contextPrepared和contextLoaded

接下来就会进行context的初始化,在完成context的准备工作后就会调用contextPrepared方法,在完成整个context的初始化工作后就会调用contextLoaded。

started和running都是在run方法中被直接调用的,srping-boot的runner就是在他们之间被调用的。

整个启动过程都是被try-catch包裹着的,任何异常都会进入handleRunFailure方法,在这个方法中会调用Listener的failed方法。

 

猜你喜欢

转载自www.cnblogs.com/luchangjiang/p/10487224.html