springboot 中事件监听模型的一种实现
前言: 事件监听模型是一种常用的设计模式,在springboot 中我们如何实现呢?
首先我们要理解事件监听中需要的几个角色
- 事件发布者 (即事件源)
- 事件监听者
- 事件本身
废话不多说直接上代码
定义事件本身
事件本身需要继承ApplicationEvent
package com.yxd;
import java.util.List;
import java.util.Map;
import org.springframework.context.ApplicationEvent;
public class DemoEvent extends ApplicationEvent{
private String type;
private List<Map> msg;
public DemoEvent(Object object, String type ,List<Map> msg) {
super(object);
this.msg = msg;
this.type = type;
}
public String getType() {
return type;
}
public void setType(String type) {
this.type = type;
}
public List<Map> getMsg() {
return msg;
}
public void setMsg(List<Map> msg) {
this.msg = msg;
}
}
如图:
定义事件源
事件源需要注入 **ApplicationContext **
package com.yxd;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.ApplicationContext;
import org.springframework.stereotype.Component;
@Component
public class DemoPublisher {
@Autowired
ApplicationContext applicationContext;
public void publish(DemoEvent event) {
applicationContext.publishEvent(event);
}
}
定义监听者
监听者有两种实现
一、需要实现 ApplicationListener
package com.yxd;
import java.util.List;
import java.util.Map;
import org.springframework.context.ApplicationListener;
import org.springframework.stereotype.Component;
@Component
public class DemoListener1 implements ApplicationListener<DemoEvent> {
@Override
public void onApplicationEvent(DemoEvent event) {
List<Map> msg = event.getMsg();
String type = event.getType();
System.out.println(" listener1接收到了 publisher 发送的消息 , 时间 "+ Time.getTime());
System.out.println("listener1 : 类型 :" + type +", 消息内容: " + msg + ", 消息处理完毕! "+ Time.getTime());
}
}
二、使用 @EventListener 注解
package com.yxd;
import java.util.List;
import java.util.Map;
import org.springframework.context.ApplicationListener;
import org.springframework.context.event.EventListener;
import org.springframework.stereotype.Component;
@Component
public class DemoListener2 {
@EventListener
public void onDemoEvent(DemoEvent demoEvent) {
System.out.println(" listener2 通过注解接收到了 publisher 发送的消息 , 时间 "+ Time.getTime());
List<Map> msg = demoEvent.getMsg();
String type = demoEvent.getType();
try {
Thread.sleep(2000);
} catch (InterruptedException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
System.out.println("listener2 : 类型 :" + type +", 消息内容: " + msg + ", 消息处理完毕! "+ Time.getTime());
}
}
此处我们还需要注意一点,此处多个监听是同步执行的(阻塞),一般情况下我们发布一个事件,是不关心谁来处理,以及处理结果的,所以我们还需要加上异步的注解
package com.yxd;
import java.util.List;
import java.util.Map;
import org.springframework.context.ApplicationListener;
import org.springframework.scheduling.annotation.Async;
import org.springframework.stereotype.Component;
@Component
public class DemoListener3 implements ApplicationListener<DemoEvent> {
@Override
@Async
public void onApplicationEvent(DemoEvent event) {
System.out.println(" listener3 接收到了 publisher 发送的消息 , 时间 "+ Time.getTime());
List<Map> msg = event.getMsg();
String type = event.getType();
try {
Thread.sleep(3000);
} catch (InterruptedException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
System.out.println("listener3 异步执行:类型 :" + type +", 消息内容: " + msg+ ", 消息处理完毕! "+ Time.getTime());
}
}
测试
package com.yxd;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.Map;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.scheduling.annotation.EnableAsync;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;
@EnableAsync
@SpringBootApplication
@RestController
public class DemoApplication {
public static void main(String[] args) {
SpringApplication.run(DemoApplication.class, args);
}
@Autowired
DemoPublisher demoPublisher;
@RequestMapping("testListener")
public String testListener() {
ArrayList<Map> list = new ArrayList<>();
HashMap<String, String> m1 = new HashMap<>();
m1.put("1", "2");
HashMap<String, String> m2 = new HashMap<>();
m2.put("3", "4");
HashMap<String, String> m3 = new HashMap<>();
m3.put("5", "6");
list.add(m1);
list.add(m2);
list.add(m3);
System.out.println("开始发布消息: " + Time.getTime());
demoPublisher.publish(new DemoEvent(this,"测试消息",list));
System.out.println("消息发布结束: " + Time.getTime());
return "消息发布成功";
}
}
我们访问接口
三个监听者都得到了消息。。
但是 listener2 通过注解 先得到了消息,延时2秒后,listener1 才得到消息,listener1 处理完后,主线程继续执行,同时listener3 开始接收到消息,开启了一个异步任务,3秒后执行结束
项目结构
最后附上Time类
package com.yxd;
import java.text.SimpleDateFormat;
import java.util.Date;
public class Time {
public static String getTime() {
return new SimpleDateFormat("HH:mm:ss").format(new Date());
}
}
springboot 中事件监听模型的一种实现的更多相关文章
- SpringBoot Application事件监听
SpringBoot Application共支持6种事件监听,按顺序分别是: ApplicationStartingEvent:在Spring最开始启动的时候触发 ApplicationEnviro ...
- SpringBoot的事件监听
事件监听的流程分为三步:1.自定义事件,一般是继承ApplicationEvent抽象类.2.定义事件监听器,一般是实现ApplicationListener接口.3.a.启动的时候,需要将监听器加入 ...
- SpringBoot中如何监听两个不同源的RabbitMQ消息队列
spring-boot如何配置监听两个不同的RabbitMQ 由于前段时间在公司开发过程中碰到了一个问题,需要同时监听两个不同的rabbitMq,但是之前没有同时监听两个RabbitMq的情况,因此在 ...
- ASP.NET Core中配置监听URLs的五种方式
原文: 5 ways to set the URLs for an ASP.NET Core app 作者: Andrew Lock 译者: Lamond Lu 默认情况下,ASP. NET Core ...
- springboot~ EventListener事件监听的使用
EventListener事件触发和监听器可以对代码解耦,在一些与业务无关的,通用的操作方法,我们可以把它设计成事件监听器,像通知,消息这些模块都可以这样设计. 事件源 @Getter @Builde ...
- SpringBoot事件监听机制及观察者模式/发布订阅模式
目录 本篇要点 什么是观察者模式? 发布订阅模式是什么? Spring事件监听机制概述 SpringBoot事件监听 定义注册事件 注解方式 @EventListener定义监听器 实现Applica ...
- Spring之事件监听(观察者模型)
目录 Spring事件监听 一.事件监听案例 1.事件类 2.事件监听类 3.事件发布者 4.配置文件中注册 5.测试 二.Spring中事件监听分析 1. Spring中事件监听的结构 2. 核心角 ...
- SpringBoot事件监听机制源码分析(上) SpringBoot源码(九)
SpringBoot中文注释项目Github地址: https://github.com/yuanmabiji/spring-boot-2.1.0.RELEASE 本篇接 SpringApplicat ...
- jQuery中的事件监听小记
一,一个事件监听的简便写法 最近发现一个jQuery中事件监听的简洁写法,感觉方便好多.同时也深感自己基础薄弱,好多东西竟然都模棱两可.因此,记录的同时,也对jQuery事件监听做个小的总结 原文链接 ...
随机推荐
- 第三方apk内置因签名导致SystemUI未启动启动问题案例分析
这个问题是刷完机正常开机后,发现手机无状态栏,下拉通知栏,按音量键也无法出现VolumeDialog,开始看到这个现象感觉是systemUI未编译到版本中去?或者是在systemserver中syst ...
- Ant使用及项目实践
1.简介 Ant 是一个 Apache 基金会下的跨平台的基于 Java 语言开发的构件工具.这是一个基于开放的操作系统构建和部署的工具,该工具需要从命令行执行. 2.特点 Ant 是基于 Java ...
- Dell XPS 13 9306安装 macOS 10.12.6
一直在考虑买一个手上的本,轻薄,办公方便.个人很喜欢mac 下的那些软件,尤其是keynote.就锁定在Macbook Pro上,但是又觉得没有什么玩头,后来一直找,觉得xps也很符合要求,就开始调查 ...
- sql server alwayson 可用性组 只读路由的设置
昨天晚上学习了[SQL Server 2012实施与管理实战指南]的第三章,于是今天想在前段时间建的那个alwayson 可用性组测试环境上也配置一下只读路由,尝试实现读写分离. 按照书中的方法,执行 ...
- python基础知识回顾之字符串
字符串是python中使用频率很高的一种数据类型,内置方法也是超级多,对于常用的方法,还是要注意掌握的. #author: Administrator #date: 2018/10/20 # pyth ...
- php二维数组去重
php二维数组去重 前言:php一维数组去重很简单,直接array_unique($arr)即可,但是二维数组去重就得自己去写了 二维数组去重方法: /* * 二维数组去重 * 注意:二维数组中的元素 ...
- 反射的作用—>实现框架的功能
框架与框架要解决的核心问题 我们做房子卖给用户住,用于用户自己安装门窗和空调,我做的房子就是框架,用户需要使用我的框架,把门窗插入进我提供的框架中.框架与工具类有区别,工具类被用户的类调用,而框架则是 ...
- 【PAT】B1069 微博转发抽奖(20 分)
一开始并没有做出来,关键是没有认真理解题,每次做题之前都应该认真读题,自己把样例模拟一下,防止漏掉信息,减慢自己写代码的速度 此题的重点在于规划逻辑,以及如何储存中奖者,用map最好,否则查找并不方便 ...
- Linux 小知识翻译 - 「环境变量」
这次,谈谈关于「环境变量」的话题. 所谓变量,就是在程序中设置的,相当于在内存中准备的「一个用来存放数据的小箱子」. 即,程序通过变量来保存值,通过变量保存的内容来进行各式各样的计算处理. 「环境变量 ...
- 【Beta Scrum】冲刺! 2/5
1. 今日完成情况 人员 学号 分工 是否完成 完成情况 胡武成 031502610 学习java后端登录验证方式,尝试编写登录api N 刚学会springmvc登录token拦截,准备明天登录注册 ...