Springboot扩展了Spring的ApplicatoionContextEvent,提供了事件:

ApplicationStartingEvent:框架启动事件

ApplicationEnvironmentPreparedEvent: springboot 对应Evironment已经准备完毕了,但是上下文还没有创建。

ApplicationContextInitializedEvent:  上下文初始化

ApplicationPreparedEvent:    springboot 上下文context创建完成,但是bean没有完全加载

ApplicationStartedEvent:   springboot 启动开始执行的事件

ApplicationReadyEvent :   调用Runners接口完毕

ApplicationFailedEvent:启动异常执行事件

 * springboot自带的事件。
* ApplicationStartingEvent
* Spring Application启动事件。事件产生的时机为ApplicationListeners注册之后,Environment或ApplicationContext可用之前,
    事件源为Spring Application自身,ApplicationStartingEvent在生命周期过程中可能会被修改,请谨慎使用。

* ApplicationEnvironmentPreparedEvent
* 事件产生的时机为Spring Application已经启动,Environment第一次可用。

* ApplicationPreparedEvent
* 事件产生的时机为Spring Application已经启动,Application Context已经完全准备好但是还没有进行刷新,在该阶段已经开始加载Bean定义并且Environment已经完全可用。

* ApplicationStartedEvent
* 事件产生的时机为Application Context已经完成刷新,ApplicationRunner application和CommandLineRunner调用之前。

* ApplicationReadyEvent
* Spring Application已经准备好对外提供服务。

* ApplicationFailedEvent
* 应用启动失败

自定义监听器的步骤:

1,建立监听类继承ApplicationListener

2, 继承方法onApplicationEvent

3, 在resource建立文件夹/META-INF/spring.factories

4, 文件里写入:

org.springframework.context.ApplicationListener=\
com.quan.sbrabbit.Listener.QuanListenerEnvPreparedEvent ,com.quan.sbrabbit.Listener.QuanListenerStartedEvent,com.quan.sbrabbit.Listener.QuanListenerPreparedEvent
/**
* spring boot 对应Enviroment已经准备完毕,但此时上下文context还没有创建。在该监听中获取到ConfigurableEnvironment
* 后可以对配置信息做操作,例如:修改默认的配置信息
*/ public class QuanListenerEnvPreparedEvent implements ApplicationListener<ApplicationEnvironmentPreparedEvent> {
@Override
public void onApplicationEvent(ApplicationEnvironmentPreparedEvent event) {
ConfigurableEnvironment environment = event.getEnvironment();
MutablePropertySources sources =environment.getPropertySources();
if (sources != null){
Iterator<PropertySource<?>> iterator = sources.iterator();
while (iterator.hasNext()){
PropertySource<?> propertySource = iterator.next();
System.out.println(propertySource.getName());
System.out.println(propertySource.getSource());
System.out.println(propertySource.getClass());
}
System.out.println("监听到ApplicationEnvironmentPreparedEvent");
// for (PropertySource<?> p :
// sources) {
// System.out.println(p.getName());
// System.out.println(p.getSource());
// System.out.println(p.getClass());
// }
}
}
}
/**
* pring boot上下文context创建完成,但此时spring中的bean是没有完全加载完成的。
* 在获取完上下文后,可以将上下文传递出去做一些额外的操作。
* 值得注意的是:在该监听器中是无法获取自定义bean并进行操作的。
*/
public class QuanListenerPreparedEvent implements ApplicationListener<ApplicationPreparedEvent> {
@Override
public void onApplicationEvent(ApplicationPreparedEvent event) {
ConfigurableApplicationContext context = event.getApplicationContext();
context.toString();
System.out.println("监听到ApplicationPreparedEvent");
}
}
public class QuanListenerStartedEvent implements ApplicationListener<ApplicationStartedEvent> {
@Override
public void onApplicationEvent(ApplicationStartedEvent event) {
SpringApplication application = event.getSpringApplication();
System.out.println(application);
//控制台或日志中会默认显示一个Banner,关闭这个东西
application.setBannerMode(Banner.Mode.OFF);
System.out.println("监听到applicationStartedEvent");
}
}

加入:

org.springframework.context.ApplicationListener=\
com.quan.sbrabbit.Listener.QuanListenerEnvPreparedEvent ,com.quan.sbrabbit.Listener.QuanListenerStartedEvent,com.quan.sbrabbit.Listener.QuanListenerPreparedEvent

运行输出:

监听到ApplicationEnvironmentPreparedEvent

  .   ____          _            __ _ _
/\\ / ___'_ __ _ _(_)_ __ __ _ \ \ \ \
( ( )\___ | '_ | '_| | '_ \/ _` | \ \ \ \
\\/ ___)| |_)| | | | | || (_| | ) ) ) )
' |____| .__|_| |_|_| |_\__, | / / / /
=========|_|==============|___/=/_/_/_/
:: Spring Boot :: (v2.3.3.RELEASE) 2020-09-01 14:10:32.063 WARN 99192 --- [ main] o.s.boot.StartupInfoLogger : InetAddress.getLocalHost().getHostName() took 5004 milliseconds to respond. Please verify your network configuration (macOS machines may need to add entries to /etc/hosts).
2020-09-01 14:10:37.067 INFO 99192 --- [ main] com.quan.sbrabbit.SbrabbitApplication : Starting SbrabbitApplication on quandeMacBook-Pro.local with PID 99192 (/Users/quan/Desktop/ALLLL/sbrabbit/target/classes started by quan in /Users/quan/Desktop/ALLLL/sbrabbit)
2020-09-01 14:10:37.068 INFO 99192 --- [ main] com.quan.sbrabbit.SbrabbitApplication : No active profile set, falling back to default profiles: default
监听到ApplicationPreparedEvent
2020-09-01 14:10:37.491 INFO 99192 --- [ main] .s.d.r.c.RepositoryConfigurationDelegate : Bootstrapping Spring Data Elasticsearch repositories in DEFAULT mode.
2020-09-01 14:10:37.505 INFO 99192 --- [ main] .s.d.r.c.RepositoryConfigurationDelegate : Finished Spring Data repository scanning in 11ms. Found 0 Elasticsearch repository interfaces.
2020-09-01 14:10:37.509 INFO 99192 --- [ main] .s.d.r.c.RepositoryConfigurationDelegate : Bootstrapping Spring Data Reactive Elasticsearch repositories in DEFAULT mode.
2020-09-01 14:10:37.511 INFO 99192 --- [ main] .s.d.r.c.RepositoryConfigurationDelegate : Finished Spring Data repository scanning in 2ms. Found 0 Reactive Elasticsearch repository interfaces.
2020-09-01 14:10:37.762 INFO 99192 --- [ main] o.s.b.w.embedded.tomcat.TomcatWebServer : Tomcat initialized with port(s): 9898 (http)
2020-09-01 14:10:37.768 INFO 99192 --- [ main] o.apache.catalina.core.StandardService : Starting service [Tomcat]
2020-09-01 14:10:37.769 INFO 99192 --- [ main] org.apache.catalina.core.StandardEngine : Starting Servlet engine: [Apache Tomcat/9.0.37]
2020-09-01 14:10:37.838 INFO 99192 --- [ main] o.a.c.c.C.[Tomcat].[localhost].[/] : Initializing Spring embedded WebApplicationContext
2020-09-01 14:10:37.839 INFO 99192 --- [ main] w.s.c.ServletWebServerApplicationContext : Root WebApplicationContext: initialization completed in 740 ms
2020-09-01 14:10:38.006 INFO 99192 --- [ main] o.s.s.concurrent.ThreadPoolTaskExecutor : Initializing ExecutorService 'applicationTaskExecutor'
2020-09-01 14:10:38.502 WARN 99192 --- [ main] o.s.data.convert.CustomConversions : Registering converter from class org.springframework.data.geo.Point to interface java.util.Map as writing converter although it doesn't convert to a store-supported type! You might want to check your annotation setup at the converter implementation.
2020-09-01 14:10:38.502 WARN 99192 --- [ main] o.s.data.convert.CustomConversions : Registering converter from interface java.util.Map to class org.springframework.data.geo.Point as reading converter although it doesn't convert from a store-supported type! You might want to check your annotation setup at the converter implementation.
2020-09-01 14:10:38.503 WARN 99192 --- [ main] o.s.data.convert.CustomConversions : Registering converter from class org.springframework.data.elasticsearch.core.geo.GeoPoint to interface java.util.Map as writing converter although it doesn't convert to a store-supported type! You might want to check your annotation setup at the converter implementation.
2020-09-01 14:10:38.503 WARN 99192 --- [ main] o.s.data.convert.CustomConversions : Registering converter from interface java.util.Map to class org.springframework.data.elasticsearch.core.geo.GeoPoint as reading converter although it doesn't convert from a store-supported type! You might want to check your annotation setup at the converter implementation.
2020-09-01 14:10:38.604 INFO 99192 --- [ main] o.s.d.elasticsearch.support.VersionInfo : Version Spring Data Elasticsearch: 4.0.3.RELEASE
2020-09-01 14:10:38.604 INFO 99192 --- [ main] o.s.d.elasticsearch.support.VersionInfo : Version Elasticsearch Client in build: 7.6.2
2020-09-01 14:10:38.605 INFO 99192 --- [ main] o.s.d.elasticsearch.support.VersionInfo : Version Elasticsearch Client used: 7.6.2
2020-09-01 14:10:38.605 INFO 99192 --- [ main] o.s.d.elasticsearch.support.VersionInfo : Version Elasticsearch cluster: 6.8.4
2020-09-01 14:10:38.605 WARN 99192 --- [ main] o.s.d.elasticsearch.support.VersionInfo : Version mismatch in between Elasticsearch Client and Cluster: 7.6.2 - 6.8.4
2020-09-01 14:10:38.688 INFO 99192 --- [ main] o.s.b.w.embedded.tomcat.TomcatWebServer : Tomcat started on port(s): 9898 (http) with context path ''
2020-09-01 14:10:38.698 INFO 99192 --- [ main] com.quan.sbrabbit.SbrabbitApplication : Started SbrabbitApplication in 16.941 seconds (JVM running for 22.495)
org.springframework.boot.SpringApplication@4a163575
监听到applicationStartedEvent

自定义事件:必须继承抽象类ApplicationEvent

public class QuanEvent extends ApplicationEvent {

    /**
* Create a new {@code ApplicationEvent}.
*
* @param source the object on which the event initially occurred or with
* which the event is associated (never {@code null})
*/
public QuanEvent(String source) {
super(source);
System.out.println("事件 "+source);
}
}

自定义监听器:监听自己定义的事件

public class QuanListenerQuanEvent implements ApplicationListener<QuanEvent> {
@Override
public void onApplicationEvent(QuanEvent event) {
System.out.println("监听到QuanEvent"); }
}

在完成springboot启动事件ApplicationStaredEvent中发布事件:

public class QuanListenerStartedEvent implements ApplicationListener<ApplicationStartedEvent> {
@Override
public void onApplicationEvent(ApplicationStartedEvent event) {
event.getApplicationContext().publishEvent(new QuanEvent("hello"));
}
}

最后加上监听器的配置:
在spring.factories追加:

,com.quan.sbrabbit.Listener.QuanListenerQuanEvent

运行结果:

也可以使用注解进行监听器的编写(这时候只需要将监听器加载到bean容器里面就行,)

使用注解@EventListener

@Component
public class QuanListenerQuanEvent {
@EventListener
public void onApplicationEvent(QuanEvent event) {
System.out.println("监听到QuanEvent"); }
}

监听事件的原理:

@FunctionalInterface
public interface ApplicationListener<E extends ApplicationEvent> extends EventListener { /**
* Handle an application event.
* @param event the event to respond to
*/
void onApplicationEvent(E event); }

监听器触发机制:

SpringApplication-run 方法
public ConfigurableApplicationContext run(String... args){
SpringApplicationRunListeners listeners = getRunListeners(args);
listeners.starting();
}
进入starting方法到SpringApplicationRunListener类
void starting() {
for (SpringApplicationRunListener listener : this.listeners) {
listener.starting();
}
}
遍历所有的SpringApplicationRunListener 再进入starting:来到EventPublishingRunListener类:
@Override
public void starting() {
this.initialMulticaster.multicastEvent(new ApplicationStartingEvent(this.application, this.args));
}
调用广播器发送 进入multicastEvent方法属于这个类:SimpleApplicationEventMulticaster
@Override
public void multicastEvent(final ApplicationEvent event, @Nullable ResolvableType eventType) {
ResolvableType type = (eventType != null ? eventType : resolveDefaultEventType(event));
Executor executor = getTaskExecutor(); //获得线程池
for (ApplicationListener<?> listener : getApplicationListeners(event, type)) {//获取对当前event感兴趣的监听器列表
if (executor != null) {
executor.execute(() -> invokeListener(listener, event));
}
else {
invokeListener(listener, event);
}
}
} 进入getApplicationListeners方法到类AbstractApplicationEventMulticaster
protected Collection<ApplicationListener<?>> getApplicationListeners(
ApplicationEvent event, ResolvableType eventType) { Object source = event.getSource();//获得事件来源 其实source就是SpringApplication

spring-boot-learning-监听事件的更多相关文章

  1. Spring boot实现监听Redis key失效事件实现和其它方式

    需求: 处理订单过期自动取消,比如下单30分钟未支付自动更改订单状态 用户绑定隐私号码当订单结束取消绑定等 解决方案1: 可以利用redis自带的key自动过期机制,下单时将订单id写入redis,过 ...

  2. 【Redis系列】Spring boot实现监听Redis key失效事件

    talk is cheap, show me the code. 一.开启Redis key过期提醒 方式二:修改配置文件 redis.conf # 默认 notify-keyspace-events ...

  3. spring boot实战(第二篇)事件监听

    http://blog.csdn.net/liaokailin/article/details/48186331 前言 spring boot在启动过程中增加事件监听机制,为用户功能拓展提供极大的便利 ...

  4. spring扩展点之三:Spring 的监听事件 ApplicationListener 和 ApplicationEvent 用法,在spring启动后做些事情

    <spring扩展点之三:Spring 的监听事件 ApplicationListener 和 ApplicationEvent 用法,在spring启动后做些事情> <服务网关zu ...

  5. 利用spring的ApplicationListener监听某一类事件的发生

    1.ApplicationListener在使用过程中可以监听某一事件的发生,可以做出相应的处理,这个方式不常用,但是在特殊情况下面还是有用的. 2.导包pom.xml <project xml ...

  6. springboot13 发布和监听事件

    spring中的事件驱动模型Event(也叫发布订阅模式),是观察者模式的一个典型的应用 好处:业务解耦,在不影响原来业务逻辑的情况下,加入其它业务 场景: app上线后已实现用户注册功能,现需要在用 ...

  7. zookeeper 监听事件 PathChildrenCacheListener

    zookeeper 监听事件 PathChildrenCacheListener PathChildrenCacheListener一次父节点注册,监听每次子节点操作,不监听自身和查询. 1.测试类: ...

  8. zookeeper 监听事件 NodeCacheListener

    zookeeper 监听事件 NodeCacheListener NodeCacheListener一次注册,每次监听,但是监听不到操作类型,不知道是增加?删除?还是修改? 1.测试类: packag ...

  9. zookeeper 监听事件 CuratorWatcher

    zookeeper 监听事件 CuratorWatcher CuratorWatcher一次注册只监听一次,不监听查询. 1.监听测试类 package com.qy.learn.zk.curator ...

  10. Redis集群环境下的键值空间监听事件实现方案

    一直想记录工作中遇到的问题和解决的方法,奈何没有找到一方乐土,最近经常反思,是否需要记录平时的点滴,后台还是决定下定决心记录一些,以便以后用到的时候找不着,实现这样的一个功能主要也是业务所需要的. 需 ...

随机推荐

  1. IP网络性能测试工具——Renix Perf

    一.Renix Perf 基于软件的网络及应用服务性能测试工具 · 双臂测试 · 单臂测试 通过测试端点产生网络流量对网络性能进行测量 · TCP.UDP.PING · 语音.视频.HTTP.FTP. ...

  2. 移动BI,移动报表平台

    ​随着大数据时代的到来,随着商业智能衍生出来的移动BI也将处于一片大好的形式中,由于智能手机.移动应用的普及,越来越多的办公软件均已支持了移动办公,这也给移动BI带来了更多的想象,通过一部手机就可以随 ...

  3. HDFS的优缺点

    HDFS是一个分布式文件存储系统,前身来自于Google发布的大数据三驾马车之一GFS (Google File System). HDFS的优点: 1.高容错 hdfs具有很高的容错性,数据自动保存 ...

  4. Oracle数据库巡检

    转至:https://blog.51cto.com/sf1314/2123068 select inst_id,status,count(*) from gv$session group by ins ...

  5. JZ-041-和为 S 的连续正数序列

    和为 S 的连续正数序列 题目描述 小明很喜欢数学,有一天他在做数学作业时,要求计算出9~16的和,他马上就写出了正确答案是100.但是他并不满足于此,他在想究竟有多少种连续的正数序列 的和为100( ...

  6. Atom 初识

    Atom记录 Git Atom默认自带Git,命令行启动,需要自己添加环境变量,同时默认安装的其他命令行工具很丰富,唯独缺少ssh-keygen,需要自己下载 Git:C:\Users\zhuyulo ...

  7. 测试平台系列(91) 编写oss管理页面

    大家好~我是米洛! 我正在从0到1打造一个开源的接口测试平台, 也在编写一套与之对应的教程,希望大家多多支持. 欢迎关注我的公众号米洛的测开日记,获取最新文章教程! 回顾 上一节我们编写好了oss相关 ...

  8. [ Skill ] load 函数优化,识别相对路径

    https://www.cnblogs.com/yeungchie/ 在 cds.lib 文件中定义库的路径,为了规范库定义的管理,经常这样做: . |-- cds.lib ------------- ...

  9. tp6微信公众号开发者模式token认证

      微信公众号开发完整教程(一) PHP7.0版本,TP5.0框架 技术标签: 微信公众号开发         因为工作的需要,这一两年对微信公众号和小程序,项目制作的比较多.所以我才打算写一篇全面的 ...

  10. Mysql备份方案总结性梳理

    Mysql备份方案总结性梳理   服务器 mysql 日志 数据库 配置 Mariadb binlog   mysql数据库备份有多么重要已不需过多赘述了,废话不多说!以下总结了mysql数据库的几种 ...