spring boot 之监听器ApplicationListener
监听器
ApplicationListener 就是spring的监听器,能够用来监听事件,典型的观察者模式。
ApplicationListener和ContextRefreshedEvent一般都是成对出现的
在IOC容器的启动过程中,当所有的bean都已经处理完成之后,spring ioc容器会有一个发布事件的动作。从AbstractApplicationContext 的源码中可以看出:
/**
* Finish the refresh of this context, invoking the LifecycleProcessor's
* onRefresh() method and publishing the
* {@link org.springframework.context.event.ContextRefreshedEvent}.
*/
protected void finishRefresh() {
// Clear context-level resource caches (such as ASM metadata from scanning).
clearResourceCaches(); // Initialize lifecycle processor for this context.
initLifecycleProcessor(); // Propagate refresh to lifecycle processor first.
getLifecycleProcessor().onRefresh(); // Publish the final event.
publishEvent(new ContextRefreshedEvent(this)); // Participate in LiveBeansView MBean, if active.
LiveBeansView.registerApplicationContext(this);
}
这样,当ioc容器加载处理完相应的bean之后,也给我们提供了一个机会(先有InitializingBean,后有ApplicationListener<ContextRefreshedEvent>),可以去做一些自己想做的事。其实这也就是spring ioc容器给提供的一个扩展的地方。我们可以这样使用这个扩展机制。
一个最简单的方式就是,让我们的bean实现ApplicationListener接口,这样当发布事件时,spring 的ioc容器就会以容器的实例对象作为事件源类,并从中找到事件的监听者,此时ApplicationListener接口实例中的onApplicationEvent(E event)方法就会被调用,我们的逻辑代码就会写在此处。这样我们的目的就达到了。但这也带来一个思考,有人可能会想,这样的代码我们也可以通过实现spring 的InitializingBean接口来实现啊,也会被spring 容器去自动调用,但是大家应该想到,如果我们现在想做的事,是必须要等到所有的bean都被处理完成之后再进行,此时InitializingBean接口的实现就不合适了,所以需要深刻理解事件机制的应用场合。
系统会存在两个容器,一个是root application context ,另一个就是我们自己的 projectName-servlet context(作为root application context的子容器)
这种情况下,就会造成onApplicationEvent方法被执行两次。为了避免上面提到的问题,我们可以只在root application context初始化完成后调用逻辑代码,其他的容器的初始化完成,则不做任何处理
简单示例代码如下:
package com.example.demo.init; import org.springframework.context.ApplicationListener;
import org.springframework.context.event.ContextRefreshedEvent;
import org.springframework.stereotype.Component; @Component
public class ZkServerInit implements ApplicationListener<ContextRefreshedEvent> {
@Override
public void onApplicationEvent(ContextRefreshedEvent context) {
if (null == context.getApplicationContext().getParent()) {
System.err.println("初始化zkServer...");
// 初始化逻辑...
System.err.println("初始化zkServer完成...");
}
}
}
spring boot 之监听器ApplicationListener的更多相关文章
- Spring Boot使用监听器Listener
之前介绍了在Spring Boot中使用过滤器:https://www.cnblogs.com/zifeiy/p/9911056.html 接下来介绍使用监听器Listener. 下面是一个例子: p ...
- Spring Boot 整合监听器
Listener是servlet规范中定义的一种特殊类,用于监听servletContext.HttpSession和servletRequest等域对象的创建和销毁事件,监听域对象的属性发生修改的事 ...
- spring boot到底帮我们做了那些事?
一.前言 上一篇介绍了注解,也是为这一篇做铺垫,传统的都是通过配置文件来启动spring,那spring boot到底是做了什么能让我们快速开发昵? 二.启动原理 看下程序启动的入口, ...
- Spring Boot SpringApplication启动类(二)
目录 前言 1.起源 2.SpringApplication 运行阶段 2.1 SpringApplicationRunListeners 结构 2.1.1 SpringApplicationRunL ...
- Spring Boot系列(四) Spring Cloud 之 Config Client
Config 是通过 PropertySource 提供. 这节的内容主要是探讨配置, 特别是 PropertySource 的加载机制. Spring Cloud 技术体系 分布式配置 服务注册/发 ...
- 精尽Spring Boot源码分析 - 日志系统
该系列文章是笔者在学习 Spring Boot 过程中总结下来的,里面涉及到相关源码,可能对读者不太友好,请结合我的源码注释 Spring Boot 源码分析 GitHub 地址 进行阅读 Sprin ...
- Spring Boot 外部化配置(一)- Environment、ConfigFileApplicationListener
目录 前言 1.起源 2.外部化配置的资源类型 3.外部化配置的核心 3.1 Environment 3.1.1.ConfigFileApplicationListener 3.1.2.关联 Spri ...
- 009-Spring Boot 事件监听、监听器配置与方式、spring、Spring boot内置事件
一.概念 1.事件监听的流程 步骤一.自定义事件,一般是继承ApplicationEvent抽象类 步骤二.定义事件监听器,一般是实现ApplicationListener接口 步骤三.启动时,需要将 ...
- Spring监听器---ApplicationListener
说到事件监听,想到的肯定是观察者模式.但是这儿主要说下spring中的监听是怎么样的流程. 这就不得不说到spring容器的refresh方法,容器启动过程中,listener相关的主要是这个三个方法 ...
随机推荐
- 最近公共祖先(lca)与树上叉分
lca的定义不在过多解释, 代码如下: inline void bfs() { queue<int>q; deep[s]=1;q.push(s); while(!q.empty()) { ...
- poj 1129 Channel Allocation(图着色,DFS)
题意: N个中继站,相邻的中继站频道不得相同,问最少需要几个频道. 输入输出: Sample Input 2 A: B: 4 A:BC B:ACD C:ABD D:BC 4 A:BCD B:ACD C ...
- 问题解决:补充安装c语言的库函数和系统调用man手册
问题解决:补充安装c语言的库函数和系统调用man手册 今日份麻麻~上课时大家的Ubuntu都可以通过man查到关于stat的库函数,但是我的Kali查出来是这样: 询问老师之后得知需要去安装相 ...
- bootstrap 4 学习笔记
一.button 颜色类 白色:btn 浅蓝色:btn btn-primary 深蓝色:btn btn-info 绿色:btn btn-success 黄色:btn btn-warning 红色:bt ...
- HDC2021:HMS Core分析服务,数智化营销闭环方案帮助开发者实现精益增长
10.22-10.24华为开发者大会2021(Together)在东莞如期举行.本次大会上,HMS Core华为分析服务作为多平台.跨设备的一站式数据分析平台以数据驱动业务智能决策为理念,带来了数智化 ...
- K8s 离线集群部署(二进制包无dashboard)
https://www.cnblogs.com/cocowool/p/install_k8s_offline.html https://www.jianshu.com/p/073577bdec98 h ...
- Qt Creator打造VScode one dark pro主题配色
1.缘由 我之前习惯使用 vscode 进行开发,对 vscode 的 one dark pro 主题情有独钟.无奈公司需要使用 Qt Creator 进行日常开发,只能暂时舍弃 vscode,采用曲 ...
- Linux下安装、配置、启动与访问RabbitMQ
一.下载 首先第一步要下载三个rpm安装包,为了方便安装与学习,给出下载途径 网盘网址:https://pan.baidu.com/s/18Z64Lb9KQpRh10RzqZBdoQ 提取码:094v ...
- Java开发介绍之JDK JRE JVM 和 环境变量配置
一.JDK>JRE>JVM JDK(Java Development Kit):Java开发工具包 JDK中包含JRE,在JDK的安装目录下有一个名为jre的目录,里面有两个文件夹bin和 ...
- PAT甲级1074 Reversing Linked List (25分)
[程序思路] 先根据地址按顺序读入节点,入栈,当栈里的元素个数等于k时全部出栈,并按出栈顺序保存,最后若栈不为空,则全部出栈并按出栈的稀饭顺序保存,最后输出各节点 注意:输入的节点中有可能存在无用节点 ...