惯性聚合 高效追踪和阅读你感兴趣的博客、新闻、科技资讯
阅读原文 在惯性聚合中打开

推荐订阅源

freeCodeCamp Programming Tutorials: Python, JavaScript, Git & More
P
Proofpoint News Feed
宝玉的分享
宝玉的分享
人人都是产品经理
人人都是产品经理
博客园_首页
爱范儿
爱范儿
博客园 - 叶小钗
aimingoo的专栏
aimingoo的专栏
S
SegmentFault 最新的问题
MyScale Blog
MyScale Blog
阮一峰的网络日志
阮一峰的网络日志
IT之家
IT之家
Microsoft Security Blog
Microsoft Security Blog
Blog — PlanetScale
Blog — PlanetScale
博客园 - 【当耐特】
Y
Y Combinator Blog
量子位
博客园 - 三生石上(FineUI控件)
让小产品的独立变现更简单 - ezindie.com
让小产品的独立变现更简单 - ezindie.com
T
The Blog of Author Tim Ferriss
月光博客
月光博客
有赞技术团队
有赞技术团队
Apple Machine Learning Research
Apple Machine Learning Research
A
About on SuperTechFans

祈雨的笔记

安全多方计算MPC spark原理解析 kueue执行源码分析 spark on k8s执行源码分析 spark-operator源码解析 系统压测遇到的缓存击穿问题 我的世界PC与安卓联机 蚂蚁金服流量投放平台的AIG改造 G1大对象致Old区占用率高 日志打印导致接口响应率下跌分析 Groovy加载类导致OOM分析 ERROR日志打印导致CPU满载 记OceanBase死锁超时 应用发版期间服务响应超时 Ark Serverless初探 系统优化复盘一二三 The user specified as a definer does not exist Kong网关初探 API网关选型调研 CPU火焰图常用工具 配置中心选型调研 root操作Nginx导致用户组错误 基于Proxifier使用代理 FastJSON字段智能匹配踩坑 Nacos初探 记一次Nginx服务器CPU满荷载故障 基于券系统分库分表的思考 limit不参与SQL成本计算致索引失效 Linux常用性能监控命令 golang低版本http2偶现400
springboot(18)事件监听
祈雨的笔记 · 2018-05-29 · via 祈雨的笔记

转载自简书本文链接地址: Springboot事件监听

先看一个demo,加入依赖

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
<properties>
<project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
<maven.compiler.source>1.8</maven.compiler.source>
<maven.compiler.target>1.8</maven.compiler.target>
</properties>

<parent>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-parent</artifactId>
<version>1.5.4.RELEASE</version>
</parent>

<dependencies>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter</artifactId>
</dependency>
</dependencies>

定义一个自定义事件,继承ApplicationEvent类

1
2
3
4
5
6
7
8
9
10
11
12




public class MyApplicationEvent extends ApplicationEvent {

private static final long serialVersionUID = 1L;

public MyApplicationEvent(Object source) {
super(source);
}
}

定义一个事件监听器MyApplicationListener实现ApplicationListener接口,

1
2
3
4
5
6
7
8
9
10
11
package com.zhihao.miao;

import org.springframework.context.ApplicationListener;

public class MyApplicationListener implements ApplicationListener<MyApplicationEvent> {

public void onApplicationEvent(MyApplicationEvent event) {
System.out.println("接收到事件:"+event.getClass());
}

}

主测试类:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
package com.zhihao.miao;


import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.context.ConfigurableApplicationContext;

@SpringBootApplication
public class Application {
public static void main(String[] args) {
SpringApplication application = new SpringApplication(Application.class);

application.addListeners(new MyApplicationListener());
ConfigurableApplicationContext context =application.run(args);

context.publishEvent(new MyApplicationEvent(new Object()));
context.close();
}
}

打印结果:
image

总结:

springboot事件监听的流程:

  1. 自定义事件,一般是继承ApplicationEvent抽象类。
  2. 定义事件监听器,一般是实现ApplicationListener接口。
  3. 配置监听器,启动的时候,需要把监听器加入到spring容器中。
  4. 发布事件。

其中第三步(将监听器纳入到spring容器)除了上面的方法之外,

1
application.addListeners(new MyApplicationListener());

还有三种方法

第二种方式

直接在MyApplicationListener类上加上@Component注解,纳入spring容器管理

1
2
3
4
5
6
7
8
9
10
11
12
13
package com.zhihao.miao;

import org.springframework.context.ApplicationListener;
import org.springframework.stereotype.Component;

@Component
public class MyApplicationListener implements ApplicationListener<MyApplicationEvent> {

public void onApplicationEvent(MyApplicationEvent event) {
System.out.println("接收到事件:"+event.getClass());
}

}

主类测试:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
package com.zhihao.miao;


import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.context.ConfigurableApplicationContext;

@SpringBootApplication
public class Application {
public static void main(String[] args) {
SpringApplication application = new SpringApplication(Application.class);
ConfigurableApplicationContext context =application.run(args);

context.publishEvent(new MyApplicationEvent(new Object()));
context.close();
}
}

image

第三种方式

在配置文件中配置

1
context.listener.classes=com.zhihao.miao.MyApplicationListener

源码分析:

进入DelegatingApplicationListener类中的onApplicationEvent方法,getListeners是获取当前项目中的所有事件监听器。

image

第四种方式

使用@EventListener注解

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
package com.zhihao.miao;

import org.springframework.context.event.EventListener;
import org.springframework.stereotype.Component;

@Component
public class MyEventHandle {






@EventListener
public void event(Object event){
System.out.println("MyEventHandle 接收到事件:" + event.getClass());
}

}

主类测试:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
package com.zhihao.miao;


import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.context.ConfigurableApplicationContext;

@SpringBootApplication
public class Application {
public static void main(String[] args) {
SpringApplication application = new SpringApplication(Application.class);
ConfigurableApplicationContext context =application.run(args);

context.publishEvent(new MyApplicationEvent(new Object()));
context.close();
}
}

打印结果:

image

源码分析:

进入@EventListener注解,文档说明中处理@EventListener是依靠EventListenerMethodProcessorbean,然后进入EventListenerMethodProcessorbean中,我们大概看一下流程,可以自己调试

image

image

总结:

配置事件监听器的四种方法

  1. SpringApplication.addListeners 添加监听器
  2. 把监听器纳入到spring容器中管理
  3. 使用context.listener.classes配置项配置(详细内容参照:DelegatingApplicationListener)
  4. 使用@EventListener注解,在方法上面加入@EventListener注解,且该类需要纳入到spring容器中管理(详细内容参照:EventListenerMethodProcessor,EventListenerFactory)

spring及springboot已经定义好的事件

spring的事件

image

springboot的事件

image

测试一下spring自带的事件:

1
2
3
4
5
6
7
8
9
10
11
12
@Component
public class MyEventHandle {





@EventListener
public void eventStop(ContextStoppedEvent event){
System.out.println("应用停止事件==========:"+event.getClass());
}
}

主类测试:

1
2
3
4
5
6
7
@SpringBootApplication
public class Application {
public static void main(String[] args) {
ConfigurableApplicationContext context = SpringApplication.run(Application.class,args);
context.stop();
}
}

测试:

image

作者:二月_春风
链接:https://www.jianshu.com/p/5f57f2aa5e2c
來源:简书
著作权归作者所有。商业转载请联系作者获得授权,非商业转载请注明出处。