基于Spring Boot应用ApplicationEvent案例场景
作者:zhangbeizhen18 发布时间:2023-08-17 22:38:12
记录:276
场景:利用Spring的机制发布ApplicationEvent和监听ApplicationEvent。
版本:Spring Boot 2.6.3
一、案例场景
1.发起restful请求,根据请求参数发布不同的事件。
2.事件监听者,监听到事件后,做预定操作。
3.本例是事件同步处理机制,即发布事件后,会同步监听事件。
二、使用类
org.springframework.context.ApplicationEvent,spring的事件对象。
org.springframework.context.ApplicationListener,事件监听者接口。
org.springframework.context.ApplicationEventPublisher,事件发布者接口。
三、代码
1.事件对象
事件对象实现ApplicationEvent。
1.1 ExampleApplicationEvent
ExampleApplicationEvent,一个抽象类。继承ApplicationEvent,自定义拓展微服务中需求的一些属性。
public abstract class ExampleApplicationEvent extends ApplicationEvent {
private static final String eventSource = "Example";
private String eventType = null;
private Object eventData = null;
public ExampleApplicationEvent(Object eventData) {
super(eventSource);
this.eventData = eventData;
}
public ExampleApplicationEvent(Object eventData, String eventType) {
super(eventSource);
this.eventData = eventData;
this.eventType = eventType;
}
public String getEventType() {
return eventType;
}
public Object getEventData() {
return eventData;
}
}
1.2 ExampleLocalApplicationEvent
ExampleLocalApplicationEvent,是抽象类ExampleApplicationEvent的实现类,在此处按需拓展属性。
public class ExampleLocalApplicationEvent extends ExampleApplicationEvent {
public ExampleLocalApplicationEvent(Object eventData) {
super(eventData);
}
public ExampleLocalApplicationEvent(Object eventData, String eventType) {
super(eventData, eventType);
}
}
1.3 EventTypeEnum
EventTypeEnum,自定义事件类型枚举,按需扩展。
public enum EventTypeEnum {
CHANGE("change", "变更事件"),
ADD("add", "新增事件");
private String id;
private String name;
public String getId() {
return id;
}
public String getName() {
return name;
}
EventTypeEnum(String id, String name) {
this.id = id;
this.name = name;
}
public static EventTypeEnum getEventTypeEnum(String id) {
for (EventTypeEnum var : EventTypeEnum.values()) {
if (var.getId().equalsIgnoreCase(id)) {
return var;
}
}
return null;
}
}
2.事件监听者
事件监听者包括接口和抽象类。
2.1 IEventListener
IEventListener,一个接口,继承ApplicationListener接口。
@SuppressWarnings("rawtypes")
public interface IEventListener extends ApplicationListener {
}
2.2 AbstractEventListener
AbstractEventListener,一个抽象类,实现IEventListener接口。并提供抽象方法便于实现类扩展和代码解耦。
public abstract class AbstractEventListener implements IEventListener {
@Override
public void onApplicationEvent(ApplicationEvent event){
if(!(event instanceof ExampleApplicationEvent)){
return;
}
ExampleApplicationEvent exEvent = (ExampleApplicationEvent) event;
try{
onExampleApplicationEvent(exEvent);
}catch (Exception e){
e.printStackTrace();
}
}
protected abstract void onExampleApplicationEvent(ExampleApplicationEvent event);
}
2.3 OrderEventListener
OrderEventListener,实现类AbstractEventListener抽象类。监听事件,并对事件做处理,是一个业务类。
@Slf4j
@Component
public class OrderEventListener extends AbstractEventListener {
@Override
protected void onExampleApplicationEvent(ExampleApplicationEvent event) {
log.info("OrderEventListener->onSpApplicationEvent,监听事件.");
Object eventData = event.getEventData();
log.info("事件类型: " + EventTypeEnum.getEventTypeEnum(event.getEventType()));
log.info("事件数据: " + eventData.toString());
}
}
3.事件发布者
事件监听者包括接口和实现类。
3.1 IEventPublisher
IEventPublisher,自定义事件发布接口,方便扩展功能和属性。
public interface IEventPublisher {
boolean publish(ExampleApplicationEvent event);
}
3.2 LocalEventPublisher
LocalEventPublisher,事件发布实现类,此类使用@Component,spring的IOC容器会加载此类。此类调用ApplicationEventPublisher的publishEvent发布事件。
@Slf4j
@Component("localEventPublisher")
public class LocalEventPublisher implements IEventPublisher {
@Override
public boolean publish(ExampleApplicationEvent event) {
try{
log.info("LocalEventPublisher->publish,发布事件.");
log.info("事件类型: " + EventTypeEnum.getEventTypeEnum(event.getEventType()));
log.info("事件数据: " + event.getEventData().toString());
SpringUtil.getApplicationContext().publishEvent(event);
}catch (Exception e){
log.info("事件发布异常.");
e.printStackTrace();
return false;
}
return true;
}
}
4.Restful请求触发事件
使用Restful请求触发事件发生。
4.1 EventController
EventController,接收Restful请求。
@Slf4j
@RestController
@RequestMapping("/event")
public class EventController {
@Autowired
private LocalEventPublisher eventPublisher;
@PostMapping("/f1")
public Object f1(@RequestBody Object obj) {
log.info("EventController->f1,接收参数,obj = " + obj.toString());
Map objMap = (Map) obj;
OrderInfo orderInfo = new OrderInfo();
orderInfo.setUserName((String) objMap.get("userName"));
orderInfo.setTradeName((String) objMap.get("tradeName"));
orderInfo.setReceiveTime(DateUtil.format(new Date(),
"yyyy-MM-dd HH:mm:ss"));
String flag = (String) objMap.get("flag");
if (StringUtils.equals("change", flag)) {
eventPublisher.publish(new ExampleLocalApplicationEvent(orderInfo,
EventTypeEnum.CHANGE.getId()));
} else if (StringUtils.equals("add", flag)) {
eventPublisher.publish(new ExampleLocalApplicationEvent(orderInfo,
EventTypeEnum.ADD.getId()));
} else {
eventPublisher.publish(new ExampleLocalApplicationEvent(orderInfo));
}
log.info("EventController->f1,返回.");
return ResultObj.builder().code("200").message("成功").build();
}
}
4.2 OrderInfo
OrderInfo,数据对象,放入事件对象中传递。
@Data
@NoArgsConstructor
public class OrderInfo {
private String userName;
private String tradeName;
private String receiveTime;
}
4.3 ResultObj
ResultObj,restful返回通用对象。
@Data
@NoArgsConstructor
@AllArgsConstructor
@Builder
public class ResultObj {
private String code;
private String message;
}
5.测试
5.1 请求信息
URL请求: http://127.0.0.1:8080/server/event/f1
入参:
{
"userName": "HangZhou",
"tradeName": "Vue进阶教程",
"flag": "add"
}
返回值:
{
"code": "200",
"message": "成功"
}
5.2 日志
输出日志:
以上,感谢。
来源:https://blog.csdn.net/zhangbeizhen18/article/details/125347511


猜你喜欢
- 如果需要使用同一类型的多个对象,可以使用数组和集合(后面介绍)。C#用特殊的记号声明,初始化和使用数组。Array类在后台发挥作用,它为数组
- 前言项目中检测人脸图片是否合法的功能,之前用的是百度的人脸识别接口,由于成本高昂不得不寻求替代方案。什么是opencv?OpenCV是一个基
- 1、什么是const? 常类型是指使用类型修饰符const说明的类型,常类型的变量或对象的值是不能被更新的。(当然,我们可以偷梁
- 本文实例讲述了Android获取当前已连接的wifi信号强度的方法,是Android程序开发中非常常见的重要技巧。分享给大家供大家参考之用。
- 如果想实现一个在桌面显示的悬浮窗,用Dialog、PopupWindow、Toast等已经不能实现了,他们基本都是在Activity之上显示
- 一、前言 在学习了循环、分支、和函数之后,可以写一些简单的小游戏来给自己的编程之路增添一
- 好久没有更新了,之前公司在做 关注/粉丝 这块儿缓存的时候,我选择的就是 Bitmap ,那时是我第一次见识到这种数据数组形式,用到的有 S
- 我就废话不多说了,大家还是直接看代码吧~private LineRenderer line;//画线line = this.gameObje
- //======================================//输出格式: hex2bin 5e.//得到: 0101
- 作用mybatis-plus接口mapper方法中的注解(如@Select)或者xml(如)传入的参数是通过#{param}或者${para
- 本文实例讲述了android编程实现设置、打开wifi热点共享供他人连接的方法。分享给大家供大家参考,具体如下:用过快牙的朋友应该知道它们在
- 一、延迟加载:LazyLoading使用延迟加载,关联的实体必须标注为virtual。本例是标注Destination类里的Lodgings
- 本文实例为大家分享了C#实现拼手气红包算法的具体代码,供大家参考,具体内容如下一、方案1:即开即中,考虑机会均等,减少金额差较大的几率可以每
- 这篇文章主要介绍了Java调用明华RF读写器DLL文件过程解析,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,
- Caffeine和Spring Boot集成Caffeine是使用Java8对Guava缓存的重写版本,在Spring Boot 2.0中将
- Android 6.0起,Android加强了权限管理,引入运行时权限概念。对于:1. Android 5.1(API 22)及以前版本,应
- 线程可以有六种状态:1.New(新创建)2.Runnable(可运行)(运行)3.Blocked(被阻塞)4.Waiting(等待)5.Ti
- 本文为大家分享了Android Toast全屏显示的具体代码,供大家参考,具体内容如下废话不说,直接上代码:private void toa
- 效果图代码 package com.jh.timelinedemo;import android.content.Context;
- java 泛型方法:泛型是什么意思在这就不多说了,而Java中泛型类的定义也比较简单,例如:public class Test