前言: 事件监听模型是一种常用的设计模式,在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 中事件监听模型的一种实现的更多相关文章

  1. SpringBoot Application事件监听

    SpringBoot Application共支持6种事件监听,按顺序分别是: ApplicationStartingEvent:在Spring最开始启动的时候触发 ApplicationEnviro ...

  2. SpringBoot的事件监听

    事件监听的流程分为三步:1.自定义事件,一般是继承ApplicationEvent抽象类.2.定义事件监听器,一般是实现ApplicationListener接口.3.a.启动的时候,需要将监听器加入 ...

  3. SpringBoot中如何监听两个不同源的RabbitMQ消息队列

    spring-boot如何配置监听两个不同的RabbitMQ 由于前段时间在公司开发过程中碰到了一个问题,需要同时监听两个不同的rabbitMq,但是之前没有同时监听两个RabbitMq的情况,因此在 ...

  4. ASP.NET Core中配置监听URLs的五种方式

    原文: 5 ways to set the URLs for an ASP.NET Core app 作者: Andrew Lock 译者: Lamond Lu 默认情况下,ASP. NET Core ...

  5. springboot~ EventListener事件监听的使用

    EventListener事件触发和监听器可以对代码解耦,在一些与业务无关的,通用的操作方法,我们可以把它设计成事件监听器,像通知,消息这些模块都可以这样设计. 事件源 @Getter @Builde ...

  6. SpringBoot事件监听机制及观察者模式/发布订阅模式

    目录 本篇要点 什么是观察者模式? 发布订阅模式是什么? Spring事件监听机制概述 SpringBoot事件监听 定义注册事件 注解方式 @EventListener定义监听器 实现Applica ...

  7. Spring之事件监听(观察者模型)

    目录 Spring事件监听 一.事件监听案例 1.事件类 2.事件监听类 3.事件发布者 4.配置文件中注册 5.测试 二.Spring中事件监听分析 1. Spring中事件监听的结构 2. 核心角 ...

  8. SpringBoot事件监听机制源码分析(上) SpringBoot源码(九)

    SpringBoot中文注释项目Github地址: https://github.com/yuanmabiji/spring-boot-2.1.0.RELEASE 本篇接 SpringApplicat ...

  9. jQuery中的事件监听小记

    一,一个事件监听的简便写法 最近发现一个jQuery中事件监听的简洁写法,感觉方便好多.同时也深感自己基础薄弱,好多东西竟然都模棱两可.因此,记录的同时,也对jQuery事件监听做个小的总结 原文链接 ...

随机推荐

  1. css文本属性用法总结

    稍稍总结了下css文本的一些属性用法,自己忘记的时候也可以用来查查,不用去查网站那么麻烦. 下面是部分总结,也希望对其他人有用 文本修饰 (1)text-decoration:  文本修饰(横线) 4 ...

  2. BD是什么角色

    BD是什么角色? 在一般创业公司里面,有了产品接下来就是运营了,而运营中很重要的一点就是BD,也就是所谓商务拓展了,俗一点说就是生意的合作拓展 https://www.jianshu.com/p/7d ...

  3. 洗礼灵魂,修炼python(28)--异常处理(2)—>运用异常

    你可能会想,卧槽这标题取的,前面不是说异常就是报错吗?异常还能运用? 是的,异常确实可以运用,可以刻意制造异常,在出现异常时捕获异常并对异常处理,所以进入本篇博文的话题—异常处理 异常处理: 异常处理 ...

  4. python第十七天---时间模块、random模块

    作完一个作业,开始新的学习: 有由今天的时间有限所有学习了以下两个模块,明天继续! 时间模块.random模块 import time #!usr/bin/env python #-*-coding: ...

  5. LNMP下动静分离部署phpmyadmin软件包

    LNMP环境肯定是先要配置好的.可以参考我之前的博客.那我们直接进行配置,我这里使用了三台机器进行动静分离部署,第一台负责nginx反向代理,第二台负责php-fpm应用程序以及mariadb的服务器 ...

  6. 计算机基础-BIOS

    BIOS--硬件和软件的纽带(Basic Input Output System) 1.含义:基本的输入输出系统,它是一组固化到计算机内主板上的一个ROM存储芯片上的程序 2.性质:它保存着计算机最重 ...

  7. 公式编辑器MathType基本使用方法总结----应付本科毕业论文完全没问题啦^_^

    本人计算数学专业毕业,写毕业论文和外文翻译的时候会遇到大量公式需要编辑,而且学校一般都要求用word.但是Word自带的公式编辑器只支持一种字体,当公式中涉及到特殊字体就不太方便了.如果用Latex来 ...

  8. box-shadow的动效制作

    突然发现原来box-shadow的功能很强大,还能做动效,下面整理下box-shadow几个效果 案例1:hover效果 <a href="/app/list">WEB ...

  9. 计算器和Menu

    MainActivity.java import android.app.Activity; import android.content.Intent; import android.os.Bund ...

  10. python五十六课——正则表达式(常用函数之match)

    函数:match(regex,string,[flags=0])参数:regex:就是正则表达式(定义了一套验证规则)string:需要被验证的字符串数据flags:模式/标志位,默认情况下(不定义) ...