当前位置: 首页 > news >正文

spring监听事件

1、spring-监听事件基本原理

  • Spring的事件监听机制和发布订阅机制是很相似的:发布了一个事件后,监听该类型事件的所有监听器会触发相应的处理逻辑

2、Spring 监听事件相关规范

在Spring中,事件监听机制主要涉及到了一下几个关键的规范(抽象类及接口):ApplicationEventApplicationListener ApplicationEventPublisher

  • ApplicationEvent: Spring的事件是符合jdk的规范的,这个抽象类继承了jdk内置的事件规范类EventObject(即jdk建议所有的事件都继承EventObject这个类)。ApplicationEvent是Spring家的事件规范。所以我们在自定义事件的时候,可以继承与ApplicationEvent,比如,Spring家自己关于容器上下文事件就又定义了一个容器上下文的时间规范ApplicationContextEvent,它同样是继承于ApplicationEvent的,只不过扩充了获取发出事件容器的方法;今后,我们同样可以在继承于ApplicationEvent的基础上定义自己的事件规范。

  • ApplicationListener:这是一个函数式接口,同样时事件监听器的规范,当监听到自己监听的事件类型时就会调用onApplicationEvent方法来执行监听逻辑

  • ApplicationEventPublisher:这同样是一个函数式接口,定义了事件发布的规范,任何的事件发布器ApplicationEventPublisher都是通过调用publishEvent来进行事件的发布

3、代码实现-自定事件

public class MyEvent extends ApplicationEvent {private user user;//注册方法也行。list<> 集合,对象public MyEvent(Object source, user user) {super(source);this.user = user;}public user getMessage() {return user;}
}

定义一个user实体类

@Data
public class user {
private String name;
private String age;}

4、监听事件

  • springboot进行事件监听有四种方式,选择任意一种即可
  • 将监听器装载入spring容器(常用)
  • 通过@EventListener注解实现事件监听(常用)
  • 手工向ApplicationContext中添加监听器
  • 在application.properties中配置监听器
  • 4.1、 监听–ApplicationListener
@Component
@Slf4j
public class MyListener1 implements ApplicationListener<MyEvent> {@Overridepublic void onApplicationEvent(MyEvent event) {//写自己的方法log.info("{}监听器1:监听到事件{}",MyListener1.class.getName(),event.getMessage());System.out.println("---------------------->监听器1:监听到事件");}
}
  • 4.2、 监听–注释
@Component
@Slf4j
public class MyListener2 {@EventListener(value = MyEvent.class)@Asyncpublic void listener(MyEvent event) {//写自己的方法log.info("{}监听器1:监听到事件{}", MyListener2.class.getName(),event.getMessage());System.out.println("---------------------->监听器1:监听到事件");}
}
  • 4.3、监听–配置文件
通过配置文application.properties中配置监听器: context.listener.classes=com.listener.MyListener1
  • 4.4、监听–手动添加监听
@SpringBootApplication
public class SpringListenerApplication {public static void main(String[] args) {ConfigurableApplicationContext run = SpringApplication.run(SpringListenerApplication.class, args);// 添加监听器run.addApplicationListener(new MyListener1());}}

5、发布事件

//使用 applicationContext  和ApplicationEventPublisher  都可以发布事件,人选则其一即可。
@RestController
@RequestMapping("/my")
public class MyController {@Autowiredprivate ApplicationContext applicationContext;//@Autowired//  private ApplicationEventPublisher applicationEventPublisher;@RequestMapping("/test")public void test() {user user = new user();user.setName("GJ");user.setAge("12");System.out.println(applicationContext.getApplicationName());applicationContext.publishEvent(new MyEvent(this,user));//    applicationEventPublisher.publishEvent(new MyEvent(this,user));}}
//直接访问即可

6、工作中使用 ----发布者模式

@Component
public class ApplicationContextUtil implements ApplicationContextAware{private static ApplicationContext applicationContext;private ApplicationContextUtil() {}public static <T> T getBean(Class<T> clazz) throws BeansException{return applicationContext.getBean(clazz);}public static void publishEvent(Object event){;applicationContext.publishEvent(event);}public static ApplicationContext getApplicationContext(){return applicationContext;}@Overridepublic void setApplicationContext(ApplicationContext context) throws BeansException {applicationContext = context;}}
  • 6.1、添加 NoticeDto 类对MyEvent进行继承
@Data
public class NoticeDto extends MyEvent{private String noticeType;public NoticeDto(Object source) {super(source);}
}
@Data
public class MyEvent extends ApplicationEvent {private String message;//ApplicationEvent 需要有参的构造,所以必须调用superpublic MyEvent(Object source) {super(source);}
}
  • 6.2、监听器
@Component
@Slf4j
public class MyListener3 {@EventListener@Async//当然这个地方也可以使用NoticeDto  作为参数。public void listener(MyEvent event) {
//        假设 MyEvent 是 NoticeDto 的父类或接口,并且某个 MyEvent 类型的对象 event 实际上是 NoticeDto 的一个实例。
//        当这个对象被传递给 listener 方法时,它仍然保持着其作为 NoticeDto 实例的所有属性和值。
//        在方法内部,通过 (NoticeDto) event 进行向下转型,将这个对象视为 NoticeDto 类型,从而可以访问 NoticeDto 特有的属性和方法。
//        由于对象的内部状态在转换过程中没有改变,所以 NoticeDto 的属性会保留其原有的值。 总的来说,转换类型并没有改变对象的实际内容,只是改变了我们与对象交互的方式。
//        因此,NoticeDto 中的属性在转换后仍然保持其原有的值。NoticeDto event1 = (NoticeDto) event;//写自己的方法log.info("{}监听器:监听到事件{}", MyListener3.class.getName(),event.getMessage());System.out.println("---------------------->监听器:监听到事件");System.out.println(event.getMessage()+"\n"+event.getSource().getClass().getName());System.out.println(event1.getNoticeType());System.out.println(event1.getMessage());}
}
  • 6.3、访问测试:
    @RequestMapping("/test2")public void test2() {//不管怎么写,都会被监听,但必须传送一个 object source,传送什么无所谓。NoticeDto noticeDto = new NoticeDto(this);noticeDto.setNoticeType("123");noticeDto.setMessage("abc");ApplicationContextUtil.publishEvent(noticeDto);}
}
//结果为:
2024-07-09 23:43:57.180  INFO 8100 --- [nio-8888-exec-1] com.example.listener.MyListener3         : com.example.listener.MyListener3监听器:监听到事件abc
---------------------->监听器:监听到事件
abc
com.example.listener.MyController
123
abc

相关文章:

  • 北京网站建设多少钱?
  • 辽宁网页制作哪家好_网站建设
  • 高端品牌网站建设_汉中网站制作
  • Obsidian 文档编辑器
  • R 绘图 - 饼图
  • 【ROS2】中级-编写动作服务器和客户端(Python)
  • 从零手写实现 nginx-26-rewrite url 重写
  • javafx基础知识
  • 【RAG KG】GraphRAG开源:查询聚焦摘要的图RAG方法
  • 打卡第7天-----哈希表
  • Istio实战教程:Service Mesh部署与流量管理
  • AutoMQ 与蚂蚁数科达成战略合作
  • 机器学习——随机森林
  • WEB安全-文件上传漏洞
  • android 使用系统工具bootchart统计开机时长
  • 2-29 基于matlab的CEEMD
  • 【开发环境】搭建PX4+ROS2+MAVROS2+Simulink+Optitrack实物联合仿真环境
  • C# 中使用模式匹配 备忘
  • 【每日笔记】【Go学习笔记】2019-01-10 codis proxy处理流程
  • golang 发送GET和POST示例
  • Hexo+码云+git快速搭建免费的静态Blog
  • iBatis和MyBatis在使用ResultMap对应关系时的区别
  • input实现文字超出省略号功能
  • IP路由与转发
  • java概述
  • js递归,无限分级树形折叠菜单
  • leetcode讲解--894. All Possible Full Binary Trees
  • MaxCompute访问TableStore(OTS) 数据
  • niucms就是以城市为分割单位,在上面 小区/乡村/同城论坛+58+团购
  • OpenStack安装流程(juno版)- 添加网络服务(neutron)- controller节点
  • React as a UI Runtime(五、列表)
  • React Native移动开发实战-3-实现页面间的数据传递
  • Theano - 导数
  • 从零开始的无人驾驶 1
  • 给Prometheus造假数据的方法
  • 小程序上传图片到七牛云(支持多张上传,预览,删除)
  • 在electron中实现跨域请求,无需更改服务器端设置
  • 追踪解析 FutureTask 源码
  • SAP CRM里Lead通过工作流自动创建Opportunity的原理讲解 ...
  • 大数据全解:定义、价值及挑战
  • #Lua:Lua调用C++生成的DLL库
  • #调用传感器数据_Flink使用函数之监控传感器温度上升提醒
  • #绘制圆心_R语言——绘制一个诚意满满的圆 祝你2021圆圆满满
  • #中国IT界的第一本漂流日记 传递IT正能量# 【分享得“IT漂友”勋章】
  • (day 2)JavaScript学习笔记(基础之变量、常量和注释)
  • (PHP)设置修改 Apache 文件根目录 (Document Root)(转帖)
  • (Redis使用系列) SpirngBoot中关于Redis的值的各种方式的存储与取出 三
  • (Redis使用系列) Springboot 使用redis的List数据结构实现简单的排队功能场景 九
  • (八十八)VFL语言初步 - 实现布局
  • (笔试题)合法字符串
  • (动态规划)5. 最长回文子串 java解决
  • (二)springcloud实战之config配置中心
  • (二十六)Java 数据结构
  • (翻译)Entity Framework技巧系列之七 - Tip 26 – 28
  • (附源码)计算机毕业设计ssm高校《大学语文》课程作业在线管理系统
  • (简单) HDU 2612 Find a way,BFS。
  • (接口封装)
  • (利用IDEA+Maven)定制属于自己的jar包