Spring Event观察者模式事件监听详解

目录
  • Spring Event事件监听
  • Spring Event同步使用
    • 自定义事件
    • 定义监听器
    • 定义发布者
    • 测试执行
    • Debug执行流程
  • Spring Event 异步使用
    • 自定义事件
    • 定义监听器
    • 定义发布者
    • 开启异步支持

Spring Event事件监听

Spring Event(Application Event)其实就是一个观察者设计模式,一个 Bean 处理完成任务后希望通知其它 Bean 或者说一个 Bean 想观察监听另一个Bean 的行为。在开发中我们经常就会遇到修改一个bean时,同时需要去修改其他得bean。或者说当一个bean得值发生变化时,需要修改另一个bean得业务。还有一些业务场景不需要在一次请求中同步完成,比如邮件发送、短信发送等。

MQ 确实可以解决这个问题,但 MQ比较重,非必要不提升架构复杂度。因此Spring Event是非常好得选择。

依赖:引入Spring得核心依赖即可

Spring Event同步使用

自定义事件

定义事件,继承 ApplicationEvent 的类成为一个事件类:

@Data
public class OrderProductEvent extends ApplicationEvent {
  /** 该类型事件携带的信息 */
  private String orderId;
  public OrderProductEvent(Object source, String orderId) {
    super(source);
    this.orderId = orderId;
  }
}

定义监听器

监听并处理事件,实现 ApplicationListener 接口或者使用 @EventListener 注解:

/**
 * 实现 ApplicationListener 接口,并指定监听的事件类型
 */
@Slf4j
@Component
public class OrderProductListener implements ApplicationListener<OrderProductEvent> {
  /**
   *  使用 onApplicationEvent 方法对消息进行接收处理
   *
   * */
  @SneakyThrows
  @Override
  public void onApplicationEvent(OrderProductEvent event) {
    String orderId = event.getOrderId();
    long start = System.currentTimeMillis();
    Thread.sleep(2000);
    long end = System.currentTimeMillis();
    log.info("{}:校验订单商品价格耗时:({})毫秒", orderId, (end - start));
  }
}

定义发布者

发布事件,通过 ApplicationEventPublisher 发布事件:

@Slf4j
@Service
@RequiredArgsConstructor
public class OrderService {
  /** 注入ApplicationContext用来发布事件 */
  private final ApplicationContext applicationContext;
  /**
   * 下单
   *
   * @param orderId 订单ID
   */
  public String buyOrder(String orderId) {
    long start = System.currentTimeMillis();
    // 1.查询订单详情
    // 2.检验订单价格 (同步处理)
    applicationContext.publishEvent(new OrderProductEvent(this, orderId));
    long end = System.currentTimeMillis();
    log.info("任务全部完成,总耗时:({})毫秒", end - start);
    return "购买成功";
  }
}

测试执行

@SpringBootTest
public class OrderServiceTest {
  @Autowired
  private OrderService orderService;
  @Test
  public void buyOrderTest() {
    orderService.buyOrder("732171109");
  }
}

c.l.l.event.OrderProductListener : 732171109:校验订单商品价格耗时:(2001)毫秒

c.llp.llpspringretry.event.OrderService : 任务全部完成,总耗时:(2005)毫秒

Debug执行流程

Spring Event 异步使用

有些业务场景不需要在一次请求中同步完成,比如邮件发送、短信发送等。

自定义事件

import lombok.AllArgsConstructor;
import lombok.Data;
@Data
@AllArgsConstructor
public class MsgEvent {
  /** 该类型事件携带的信息 */
  public String orderId;
}

定义监听器

推荐使用 @EventListener 注解:

@Slf4j
@Component
public class MsgListener {
  @Async
  @SneakyThrows
  @EventListener(MsgEvent.class)
  public void sendMsg(MsgEvent event) {
    String orderId = event.getOrderId();
    long start = System.currentTimeMillis();
    log.info("开发发送短信");
    log.info("开发发送邮件");
    Thread.sleep(4000);
    long end = System.currentTimeMillis();
    log.info("{}:发送短信、邮件耗时:({})毫秒", orderId, (end - start));
  }
}

定义发布者

@Slf4j
@Service
@RequiredArgsConstructor
public class OrderService {
  /** 注入ApplicationContext用来发布事件 */
  private final ApplicationContext applicationContext;
  /**
   * 下单
   *
   * @param orderId 订单ID
   */
  public String buyOrder(String orderId) {
    long start = System.currentTimeMillis();
    // 1.查询订单详情
    // 2.检验订单价格 (同步处理)
//    applicationContext.publishEvent(new OrderProductEvent(this, orderId));
    // 3.短信通知(异步处理) 新开线程执行监听得业务
    applicationContext.publishEvent(new MsgEvent(orderId));
    long end = System.currentTimeMillis();
    log.info("任务全部完成,总耗时:({})毫秒", end - start);
    return "购买成功";
  }
}

开启异步支持

@EnableAsync开启异步支持

@EnableAsync
@EnableRetry
@SpringBootApplication
public class LlpSpringRetryApplication {
    public static void main(String[] args) {
        SpringApplication.run(LlpSpringRetryApplication.class, args);
    }
}

c.llp.llpspringretry.event.OrderService : 任务全部完成,总耗时:(6)毫秒

c.llp.llpspringretry.event.MsgListener : 开发发送短信

c.llp.llpspringretry.event.MsgListener : 开发发送邮件

到此这篇关于Spring Event观察者模式事件监听详解的文章就介绍到这了,更多相关Spring Event事件监听内容请搜索我们以前的文章或继续浏览下面的相关文章希望大家以后多多支持我们!

(0)

相关推荐

  • springboot 事件监听器的案例详解

    目录 前言 引导案例 一.通过实现ApplicationListener接口实现步骤 1.自定义一个事件类(对象),继承ApplicationEvent 2.自定义业务类实现ApplicationListener 接口 3.主线业务发布事件 二.通过添加 @EventListener 注解来实现 三.使用异步 前言 在spring框架中,提供了很多动态灵活且可扩展的机制,开发者可以利用这些机制完成一些巧妙的业务,实现一些业务中的解耦, 引导案例 下面看一个简单的案例, @Configuratio

  • Java Spring 事件监听详情解析

    目录 前言 需求背景 事件概念 定义 组成 事件实现 时序图 前言 前段时间因为工作的需要用到Spring事件,翻翻文档将功能实现了,但是存在少许理解不畅的地方,今天有空来梳理梳理. 需求背景 叶子同学在新入职公司,老大让他实现登陆功能,叶子随手写完,上线无bug,一切安好 //登陆伪代码 public void login(....){ userLogin(....); } 几天之后,老大说为维护用户的粘度,每天登陆送积分.叶子同学,二话不说,一顿操作后,上线无bug,一切安好 //登陆伪代码

  • Spring事件监听器之@EventListener原理分析

    目录 Spring事件监听器之@EventListener原理 一.解析@EventListener前的准备工作 二.开始解析@EventListener EventListener.Factory EventListener.Factory监听网络请求全过程 问题是如何将这些数据回传回来呢 Spring事件监听器之@EventListener原理 Spring为我们提供的一个事件监听.订阅的实现,内部实现原理是观察者设计模式:为的就是业务系统逻辑的解耦,提高可扩展性以及可维护性.事件发布者并不

  • Spring事件监听详解

    一.观察者模式 先来看下观察者模式,举个例子 警察和军人是观察者,犯罪嫌疑人是被观察者 代码实现: 定义被观察者接口: 定义观察者接口 定义坏人 定义好人: 定义好人2: 测试: 或者用JDK自带的观察者模式 定义坏人: 定义好人: 测试: 结果: 最后来总结一下,看下spring的事件 二.spring事件 下面来看下源码 1 初始化事件广播器 可以看到如果没有自定义的事件广播器,默认是使用SimpleApplicationEventMulticaster的 三.注册监听器 其实就是把监听器添

  • springboot 事件监听的实现方法

    定义事件 @Getter public class TestEvent extends ApplicationEvent { private String msg; public TestEvent(Object source, String msg) { super(source); this.msg = msg; } } 定义事件监听(注解方式) @Component public class TestListen { @EventListener public void testListe

  • Spring boot事件监听实现过程解析

    事件监听其实我们并不陌生,简单来讲,当程序达到了某个特定的条件,程序就会自动执行一段指令.在spring 中也一样,我们可以使用spring中的事件监听来实现某些特定的需求. 发布事件 既然要监听事件,首先要发布我们的事件嘛.在spring中发布事件我们可以通过继承ApplicationEvent 来发布我们的事件类. @Data public class SendEvent extends ApplicationEvent { public SendEvent(Object source) {

  • Spring Event观察者模式事件监听详解

    目录 Spring Event事件监听 Spring Event同步使用 自定义事件 定义监听器 定义发布者 测试执行 Debug执行流程 Spring Event 异步使用 自定义事件 定义监听器 定义发布者 开启异步支持 Spring Event事件监听 Spring Event(Application Event)其实就是一个观察者设计模式,一个 Bean 处理完成任务后希望通知其它 Bean 或者说一个 Bean 想观察监听另一个Bean 的行为.在开发中我们经常就会遇到修改一个bean

  • Spring Boot应用事件监听示例详解

    前言 本文主要给大家介绍了关于Spring Boot应用事件监听的相关内容,分享出来供大家参考学习,下面话不多说了,来一起看看详细的介绍吧 1. Spring Boot特有的应用事件 除了Spring框架的事件,Spring Boot的SpringApplication也发送了一些自己的事件: ApplicationStartingEvent:在任何处理(除了注册listener和initializer)开始之前发送. ApplicationEnvironmentPreparedEvent: 在

  • Android 自定义精美界面包含选项菜单 上下文菜单及监听详解流程

    目录 activity_main.xml源码 main.xml源码 main_menu.xml MainActivity.java源码 先放实现结果 activity_main.xml.main_menu.xml和main.xml设计界面完成如下: MainActivity.java运行结果.长按选择英雄和长按选择铭文结果如下: 目录 需要在menu下创建如下文件,把图片插入drawable activity_main.xml源码 <?xml version="1.0" enco

  • SpringBoot事件发布和监听详解

    目录 概述 事件监听的结构 Publisher,Event和Listener的关系 事件 发布者 监听者 总结 概述 ApplicationEvent以及Listener是Spring为我们提供的一个事件监听.订阅的实现,内部实现原理是观察者设计模式,设计初衷也是为了系统业务逻辑之间的解耦,提高可扩展性以及可维护性.事件发布者并不需要考虑谁去监听,监听具体的实现内容是什么,发布者的工作只是为了发布事件而已.事件监听的作用与消息队列有一点类似. 事件监听的结构 主要有三个部分组成: 发布者Publ

  • C#事件管理器如何清空所有监听详解

    C#事件使用+= -=使用起来是很方便的,但是却不能整体清空所有事件.比如一个常见的操作,打开界面注册监听事件,关闭界面需要把所有的事件清空了,这要在写一堆-=操作,如果漏清空的话肯定会造成隐患,如果在lua里这个很容易,但是C#却不行.所以我想了个办法,对Action和Func进行一次包装,就可以解决这个问题了. 这里我只封装了两个参数,大家可以继续拓展新的参数,我在项目里一共拓展了5个参数,完全够用了. using System; using System.Collections.Gener

  • 关于uniapp微信小程序左上角返回按钮的监听详解

    目录 项目场景: 问题描述: 原因分析: 解决方案一: 解决方案二: 结语 项目场景: uni-app 开发微信小程序,界面中点击左上角的返回按钮或者是系统自带的虚拟返回操作,返回前监听用户是否在页面内进行了相应操作,如果有则进行提示(提示用户是否确定要返回),如果没有则直接返回. 问题描述: uni-app 页面生命周期中有 onBackPress ,不过不支持微信小程序.翻看微信小程序官方文档,并未发现可以监听到左上角返回按钮的事件.查阅相关技术文档,确认微信小程序现阶段并没有提供监听左上角

  • Android中GIF动图的播放控制和监听详解

    前言 最近接手的项目里涉及到了 GIF 动图的播放与监听,在上一版本中对于 GIF 的处理是由 H5 来实现的,因为考虑到用户体验,因此现在的需求是将这块儿原生化,途中差点误入歧途!下面来看看详细的介绍吧. Android 中 GIF 动图处理与监听 刚开始第一个想到的便是 glide , 但是自认为 glide 不能够控制 GIF 以及去监听它,所以网上去搜寻别的方法.看到有一个方案是将图片分帧,一张张的去用逐帧动画来实现. 我开始怀疑给这个解决方案的人了,都什么时代了还做这种费力不讨好,大量

  • Android中wifi与数据流量的切换监听详解

    最近在做一个wifi和移动数据的监控功能,来来回回折腾了一阵子,这个模块的主要功能是监听整个APP的wifi与数据流量的切换,让用户使用专用流量,而不是用wifi,给一个弹窗,点击确认,自动切换数据流量,关闭wifi.我的思路是写一个静态广播,监听在广播里面进行监听,启用系统弹窗,点击确认,自动切换网络,这里面有一个坑就是弹窗会在广播中多次被调用,其实只调用了一次,但是实际上多次调用系统的弹窗会一个叠加一个,搞了好久,终于搞好了,原来是系统广播导致的叠加,详情看代码: 网络封装类Connecti

  • java实现emqx设备上下线监听详解

    目录 正文 第一步,emqx配置aclz 第二步 代码中实现主题的订阅 在接受主题回调地方接受消息即可 正文 我们在做物联网项目的时候,需要实时的检测设备是否在线,emqx就为我们提供了一个很好的上下线监听机制,这里我就给大家讲一下,如何实现设备上下线的监听 emqx提供了系统主题进行监听 第一步,emqx配置aclz 增加默认系统监听 第二步 代码中实现主题的订阅 在接受主题回调地方接受消息即可 这里就实现了emq对设备的上下线监听啦,更多关于java emqx上下线监听的资料请关注我们其它相

随机推荐