Spring Boot的Listener机制的用法和实现原理详解
之前在介绍了在spring-boot启动过程中调用runner的原理,今天我们介绍另外一种可以实现相似功能的机制:spring-boot的Listener机制。
通过注册Listener,可以实现对于spring-boot整个生命周期各个状态变化进行监听,然后执行相应的业务代码。我们只需要监听其中几个启动状态就能够实现runner一样的功能了。
如何使用Spring Boot Listener
要想在spring-boot工程中加入自己实现的Listener,只需要完成一下两步动作:
- 实现SpringApplicationRunListener接口
- 在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的原理可以总结为:
- 加载SpringApplicationRunListener接口的实现类
- 在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方法。
Spring Boot的Listener机制的用法和实现原理详解的更多相关文章
- Spring Boot中对自然语言处理工具包hanlp的调用详解
概 述 HanLP 是基于 Java开发的 NLP工具包,由一系列模型与算法组成,目标是普及自然语言处理在生产环境中的应用.而且 HanLP具备功能完善.性能高效.架构清晰.语料时新.可自定义的特点, ...
- Spring Boot 揭秘与实战 源码分析 - 工作原理剖析
文章目录 1. EnableAutoConfiguration 帮助我们做了什么 2. 配置参数类 – FreeMarkerProperties 3. 自动配置类 – FreeMarkerAutoCo ...
- Spring Boot干货系列:(三)启动原理解析
Spring Boot干货系列:(三)启动原理解析 2017-03-13 嘟嘟MD 嘟爷java超神学堂 前言 前面几章我们见识了SpringBoot为我们做的自动配置,确实方便快捷,但是对于新手来说 ...
- Spring框架系列(7) - Spring IOC实现原理详解之IOC初始化流程
上文,我们看了IOC设计要点和设计结构:紧接着这篇,我们可以看下源码的实现了:Spring如何实现将资源配置(以xml配置为例)通过加载,解析,生成BeanDefination并注册到IoC容器中的. ...
- 2017.3.31 spring mvc教程(二)核心流程及配置详解
学习的博客:http://elf8848.iteye.com/blog/875830/ 我项目中所用的版本:4.2.0.博客的时间比较早,11年的,学习的是Spring3 MVC.不知道版本上有没有变 ...
- 整合Spring时Service层为什么不做全局包扫描详解
合Spring时Service层为什么不做全局包扫描详解 一.Spring和SpringMVC的父子容器关系 1.讲问题之前要先明白一个关系 一般来说,我们在整合Spring和SpringMVC这两个 ...
- spring盒springMVC整合父子容器问题:整合Spring时Service层为什么不做全局包扫描详解
整合Spring时Service层为什么不做全局包扫描详解 一.Spring和SpringMVC的父子容器关系 1.讲问题之前要先明白一个关系 一般来说,我们在整合Spring和SpringMVC这两 ...
- Spring框架系列(8) - Spring IOC实现原理详解之Bean实例化(生命周期,循环依赖等)
上文,我们看了IOC设计要点和设计结构:以及Spring如何实现将资源配置(以xml配置为例)通过加载,解析,生成BeanDefination并注册到IoC容器中的:容器中存放的是Bean的定义即Be ...
- ASP.NET MVC 5 学习教程:Edit方法和Edit视图详解
原文 ASP.NET MVC 5 学习教程:Edit方法和Edit视图详解 起飞网 ASP.NET MVC 5 学习教程目录: 添加控制器 添加视图 修改视图和布局页 控制器传递数据给视图 添加模型 ...
随机推荐
- Angular4
1.安装node.js 官网下载安装 npm会跟着被自动安装 2.安装Angular工具(AngularCli) 1.使用npm安装 npm install -g @angular/cli 2使用cn ...
- mongodb 案例 ~ 经典故障案例
一 简介:此文汇总遇到过和搜集过的故障案例 二 场景案例 1 问题描述: mongo集群在无任何业务情况下,mongos所在服务器cpu突然被打满,内核日志报错 mongos被hung住,非常奇怪的问 ...
- linux 初识系统分区
- 20165234 《Java程序设计》第三周学习总结
第三周学习总结 教材学习内容总结 第四章 编程语言的几个发展阶段: 面向机器语言 面向过程语言 面向对象语言 类 1. 类声明: class People { ... } class 动物 { ... ...
- HDOJ 3308 LCIS (线段树)
题目: Problem Description Given n integers.You have two operations:U A B: replace the Ath number by B. ...
- Shell-find . -type f -name "*.jpg" -print | xargs tar -czvf images.tar.gz
查找所有的 jpg 文件,并且压缩它们: find . -type f -name "*.jpg" -print | xargs tar -czvf images.tar.gz
- NandFlash和iNand【转】
转自:https://www.cnblogs.com/PengfeiSong/p/6380447.html nand 1.nand的单元组织:block与page(大页Nand与小页Nand)(1)N ...
- Python运维开发基础07-文件基础【转】
一,文件的基础操作 对文件操作的流程 [x] :打开文件,得到文件句柄并赋值给一个变量 [x] :通过句柄对文件进行操作 [x] :关闭文件 创建初始操作模板文件 [root@localhost sc ...
- python3+selenium入门16-窗口截图
有时候需要把一些浏览器当前窗口截图下来,比如操作抱错的时候.WebDriver类下.get_screenshot_as_file()方法可窗口截图,需要传入一个截图文件名的路径.window要用\\当 ...
- C# 基础之const
1.使用 const 关键字来声明某个常量字段或常量局部变量.常量字段和常量局部变量不是变量并且不能修改. 常量可以为数字.布尔值.字符串或 null 引用(Constants can be numb ...