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

 更新时间:2022年08月18日 10:11:58   作者:llp1110  
这篇文章主要介绍了Java 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事件监听内容请搜索脚本之家以前的文章或继续浏览下面的相关文章希望大家以后多多支持脚本之家!

相关文章

  • Java spring webmvc如何实现控制反转

    Java spring webmvc如何实现控制反转

    这篇文章主要介绍了Java spring webmvc如何实现控制反转,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要的朋友可以参考下
    2020-08-08
  • java实现简易版简易版dubbo

    java实现简易版简易版dubbo

    dubbo是阿里开源的rpc框架,目前是apache顶级开源项目,可以用来构建微服务。本文主要介绍了如何通过java实现简易版的dubbo,感兴趣的小伙伴可以了解一下
    2021-11-11
  • java常见事件响应方法实例汇总

    java常见事件响应方法实例汇总

    这篇文章主要介绍了java常见事件响应方法,对于初学者有很好的参考借鉴价值,分享给大家,需要的朋友可以参考下
    2014-08-08
  • springcloud中Feign超时提示Read timed out executing POST的问题及解决方法

    springcloud中Feign超时提示Read timed out executing

    Feign接口调用分两层,Ribbon的调用和Hystrix调用,理论上设置Ribbon的时间即可,但是Ribbon的超时时间和Hystrix的超时时间需要结合起来,这篇文章给大家介绍springcloud之Feign超时提示Read timed out executing POST问题及解决方法,感兴趣的朋友一起看看吧
    2024-01-01
  • IDEA如何修改配置文件的存放位置

    IDEA如何修改配置文件的存放位置

    这篇文章主要介绍了IDEA如何修改配置文件的存放位置,具有很好的参考价值,希望对大家有所帮助。如有错误或未考虑完全的地方,望不吝赐教
    2021-12-12
  • SpringBoot中使用configtree读取树形文件目录中的配置详解

    SpringBoot中使用configtree读取树形文件目录中的配置详解

    这篇文章主要介绍了SpringBoot中使用configtree读取树形文件目录中的配置详解,configtree通过spring.config.import + configtree:前缀的方式,加载以文件名为key、文件内容为value的配置属性,需要的朋友可以参考下
    2023-12-12
  • 详解Java编程中包package的内容与包对象的规范

    详解Java编程中包package的内容与包对象的规范

    这篇文章主要介绍了Java编程中包package的内容与包对象的规范,是Java入门学习中的基础知识,需要的朋友可以参考下
    2015-12-12
  • java生成自增编号数字的问题

    java生成自增编号数字的问题

    这篇文章主要介绍了java生成自增编号数字的问题,具有很好的参考价值,希望对大家有所帮助。如有错误或未考虑完全的地方,望不吝赐教
    2022-09-09
  • Spring Boot 中的 @DateTimeFormat 和 @JsonFormat 的用法及作用详解

    Spring Boot 中的 @DateTimeFormat 和 @JsonFormat 的用法及作用详解

    本文介绍了SpringBoot中的@DateTimeFormat和@JsonFormat注解的用法,解释了它们在处理日期和时间数据时的作用,并通过实例代码展示了如何在REST控制器中使用这些注解,感兴趣的朋友跟随小编一起看看吧
    2024-11-11
  • Java 接口和抽象类的区别详解

    Java 接口和抽象类的区别详解

    在面向对象编程中,抽象类和接口是两个经常被用到的语法概念,是面向对象四大特性,以及很多设计模式、设计思想、设计原则编程实现的基础。本文将主要讲解二者的区别
    2021-05-05

最新评论