之前在介绍了在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方法。

Spring Boot的Listener机制的用法和实现原理详解的更多相关文章

  1. Spring Boot中对自然语言处理工具包hanlp的调用详解

    概 述 HanLP 是基于 Java开发的 NLP工具包,由一系列模型与算法组成,目标是普及自然语言处理在生产环境中的应用.而且 HanLP具备功能完善.性能高效.架构清晰.语料时新.可自定义的特点, ...

  2. Spring Boot 揭秘与实战 源码分析 - 工作原理剖析

    文章目录 1. EnableAutoConfiguration 帮助我们做了什么 2. 配置参数类 – FreeMarkerProperties 3. 自动配置类 – FreeMarkerAutoCo ...

  3. Spring Boot干货系列:(三)启动原理解析

    Spring Boot干货系列:(三)启动原理解析 2017-03-13 嘟嘟MD 嘟爷java超神学堂 前言 前面几章我们见识了SpringBoot为我们做的自动配置,确实方便快捷,但是对于新手来说 ...

  4. Spring框架系列(7) - Spring IOC实现原理详解之IOC初始化流程

    上文,我们看了IOC设计要点和设计结构:紧接着这篇,我们可以看下源码的实现了:Spring如何实现将资源配置(以xml配置为例)通过加载,解析,生成BeanDefination并注册到IoC容器中的. ...

  5. 2017.3.31 spring mvc教程(二)核心流程及配置详解

    学习的博客:http://elf8848.iteye.com/blog/875830/ 我项目中所用的版本:4.2.0.博客的时间比较早,11年的,学习的是Spring3 MVC.不知道版本上有没有变 ...

  6. 整合Spring时Service层为什么不做全局包扫描详解

    合Spring时Service层为什么不做全局包扫描详解 一.Spring和SpringMVC的父子容器关系 1.讲问题之前要先明白一个关系 一般来说,我们在整合Spring和SpringMVC这两个 ...

  7. spring盒springMVC整合父子容器问题:整合Spring时Service层为什么不做全局包扫描详解

    整合Spring时Service层为什么不做全局包扫描详解 一.Spring和SpringMVC的父子容器关系 1.讲问题之前要先明白一个关系 一般来说,我们在整合Spring和SpringMVC这两 ...

  8. Spring框架系列(8) - Spring IOC实现原理详解之Bean实例化(生命周期,循环依赖等)

    上文,我们看了IOC设计要点和设计结构:以及Spring如何实现将资源配置(以xml配置为例)通过加载,解析,生成BeanDefination并注册到IoC容器中的:容器中存放的是Bean的定义即Be ...

  9. ASP.NET MVC 5 学习教程:Edit方法和Edit视图详解

    原文 ASP.NET MVC 5 学习教程:Edit方法和Edit视图详解 起飞网 ASP.NET MVC 5 学习教程目录: 添加控制器 添加视图 修改视图和布局页 控制器传递数据给视图 添加模型 ...

随机推荐

  1. 添加日志(配置spring)---Java_web

    一.配置日志--以下三部 1.配置web.xml;  2.配置 log4j.properties;  3.配置jar包 以下是文件目录 二.配置 web.xml (注意:下面的classpath即lo ...

  2. MySql cmd下的学习笔记 —— 有关多表查询的操作(多表查询练习题及union操作)

    先建立一张 m 表 mysql> create table m ( -> mid int, -> hid int, -> gid int, ), -> matime da ...

  3. Informatic 使用过程中的问题

    1.database driver error ORA-12154 1)检查监听是否启动 2)是否在tnsnames.ora中配置

  4. java知识点4

    架构篇 分布式 数据一致性.服务治理.服务降级 分布式事务 2PC.3PC.CAP.BASE. 可靠消息最终一致性.最大努力通知.TCC Dubbo 服务注册.服务发现,服务治理 分布式数据库 怎样打 ...

  5. 20165325 2017-2018-2 《Java程序设计》结对编程_第一周:四则运算

    一.码云链接 项目名称FAO 码云链接 二.需求分析 实现一个命令行程序: 自动生成小学四则运算题目(加.减.乘.除) 支持整数 支持多运算符(比如生成包含100个运算符的题目) 支持真分数 统计正确 ...

  6. java中equals,hashcode和==的区别

    https://www.cnblogs.com/kexianting/p/8508207.html

  7. go 多维度 Map 的数据存取

    多维度 Map 的数据存取 一维情况下的 map 做存取很简单,而二维以上的情况就得小心了. 先来看一个例子: m:=make(map[string]map[string]int)   c:=make ...

  8. 【转】python 历险记(四)— python 中常用的 json 操作

    [转]python 历险记(四)— python 中常用的 json 操作 目录 引言 基础知识 什么是 JSON? JSON 的语法 JSON 对象有哪些特点? JSON 数组有哪些特点? 什么是编 ...

  9. date命令以及date -d使用

    date -d '2 days ago' //显示2天前的时间,2019年 02月 10日 星期日 08:53:28 CST date -d "2 days ago" +%Y%m% ...

  10. Shell-cat url-list.txt | xargs wget -c

    假如你有一个文件包含了很多你希望下载的 URL,你能够使用 xargs下载所有链接: cat url-list.txt | xargs wget -c