【java】spring中时间机制以及与MQ对比

事件机制

背景

  • 场景 1:在项目管理平台中,当单子的属性发生变更时,异步发送消息给相关变更人。
  • 场景 2:外部上报某对象到服务器,该对象某字段的值需要到第三方获取后填充。

观察者模式

定义了对象之间的一种一对多依赖关系。当一个对象状态改变时,所有依赖于它的对象都会收到通知并自动更新。

实现方式

  1. 注册:观察者注册到被观察对象中,被观察对象将观察者存放在容器中。
  2. 通知:被观察对象发生变化时,获取容器中所有注册的观察者并通知。
  3. 撤销注册:观察者可撤销注册,被观察对象从容器中移除该观察者。

Spring 事件机制概述

Spring 事件机制是观察者模式的一种实现,支持事件的发布和订阅,解耦组件之间的逻辑。

示例:订单支付事件

在电商系统中,当订单完成支付后,可以发布一个事件,触发以下响应:

  • 发送通知给用户。
  • 更新库存。

事件相关的重要概念

事件(ApplicationEvent)

  • 所有事件的基类,继承自 java.util.EventObject。
  • 自定义事件需要继承 ApplicationEvent。
    示例:定义订单支付事件:
java 复制代码
import org.springframework.context.ApplicationEvent;

public class OrderPaidEvent extends ApplicationEvent {
    private Order order;

    public OrderPaidEvent(Order order) {
        super(order);
        this.order = order;
    }

    public Order getOrder() {
        return order;
    }
}

事件发布者(ApplicationEventPublisher)

  • 功能 :用于发布事件。通过 publishEvent 方法发布自定义事件。
  • 示例:订单服务中发布支付成功事件:
java 复制代码
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.ApplicationEventPublisher;

public class OrderService {
    @Autowired
    private ApplicationEventPublisher publisher;

    public void paySuccess(Order order) {
        // 更新订单状态等业务逻辑
        publisher.publishEvent(new OrderPaidEvent(order));
    }
}

事件监听器(ApplicationListener)

  • 功能 :监听并处理事件,需实现 ApplicationListener 接口。
  • 示例:通知监听器处理订单支付事件:
java 复制代码
import org.springframework.context.ApplicationListener;

public class NotificationListener implements ApplicationListener<OrderPaidEvent> {
    @Override
    public void onApplicationEvent(OrderPaidEvent event) {
        Order order = event.getOrder();
        // 发送通知给用户(邮件、短信等)
    }
}

事件发布和监听的流程

  1. 事件发布:发布者调用 publishEvent 发布事件。
  2. 事件广播:Spring 查找注册的监听器。
  3. 事件处理:调用监听器的 onApplicationEvent 方法处理事件。

Spring 事件机制的优缺点

优点

  1. 松耦合 :
    • 事件发布者和事件监听器之间没有直接依赖,降低了模块之间的耦合性。
    • 方便后续扩展和维护。
  2. 内置支持 :
    • 完全集成在 Spring 框架中,无需额外配置即可使用。
  3. 异步能力 :
    • 借助 @Async 注解轻松实现异步事件处理,提升性能。
  4. 便捷性 :
    • 通过简单的注解(如 @EventListener)实现监听器,无需额外代码。

缺点

  1. 受限于容器 :
    • 依赖 Spring 容器运行,无法跨系统或分布式使用。
  2. 可靠性不足 :
    • 缺乏内置的持久化和重试机制,容易丢失未处理的事件。
  3. 适用场景局限 :
    • 更适合单体应用中的事件处理,不适用于高并发、大规模分布式场景。

MQ 的优缺点

优点

  1. 高可靠性 :
    • 提供消息持久化和 ACK 确认机制,确保消息不会丢失。
  2. 跨系统支持 :
    • 支持分布式部署,适合跨语言、跨系统的通信。
  3. 高并发处理 :
    • 设计为支持大规模消息传递,能应对高流量场景。
  4. 事务支持 :
    • 提供强大的事务管理能力,例如 Kafka 的事务 API。
  5. 消息顺序保证 :
    • 通过分区或队列设计,支持严格的消息顺序。

缺点

  1. 复杂性 :
    • 部署和运维成本高,尤其是在分布式部署中。
  2. 开发成本 :
    • 消费者与生产者的逻辑设计复杂,尤其是需要保证事务一致性时。
  3. 性能瓶颈 :
    • 在高并发下,需优化 MQ 的配置和资源,可能会增加硬件成本。

适用场景对比

场景 Spring 事件机制 消息队列(MQ)
单体应用内部事件传递 ✅ 适合,低延迟 ❌ 过于复杂,性能未必优于直接调用
分布式系统通信 ❌ 需额外实现跨容器事件传递 ✅ 天然支持分布式,适合跨系统通信
高可靠性场景 ❌ 容器故障可能导致事件丢失 ✅ 提供持久化和重试机制,确保消息不丢失
大规模并发消息处理 ❌ 不支持高并发场景 ✅ 专为高并发设计,支持海量消息传递
事务一致性要求高的场景 ❌ 无原生事务支持,需手动处理 ✅ 提供事务机制(如 Kafka 事务 API)
消息顺序严格要求的场景 ❌ 无顺序性保障 ✅ 支持消息顺序(如 Kafka 分区内消息有序)

总结

  1. Spring 事件机制:

    • 简单易用,适合单体应用内部的轻量级事件处理。
    • 更适合解耦应用内部的模块之间的业务逻辑。
  2. 消息队列(MQ):

    • 功能强大,适合分布式、高并发和高可靠性场景。
    • 更适合跨系统通信、大规模消息传递以及严格的事务需求。

选择使用哪种机制,应根据实际的业务场景需求进行权衡。

相关推荐
文丑颜不良啊2 分钟前
LeetCode2141~2160题目解析
java·leetcode
LabVIEW开发9 分钟前
LabVIEW 连接板:28 个端子怎么排,优先级怎么定
java·算法·labview
天天被压力42 分钟前
【A股分钟级高频数据完全手册 #07】北交所历史分钟K线接口:京市Pro版分时批量
java·人工智能·python
天天被压力1 小时前
【A股分钟级高频数据完全手册 #08】股票日、分时数据接口对比:普通分时与Pro版差异实测
java·人工智能·python
特立独行的猫A1 小时前
AI 时代,我为什么推荐用 cj-tauri 开发桌面应用
java·后端·python
金銀銅鐵1 小时前
从一个类名到一张类图:用反射自动生成 PlantUML
java·后端·uml
nice_lcj5202 小时前
Java 并发容器入门:ConcurrentHashMap、CopyOnWriteArrayList、阻塞队列
java·面试·并发编程·阻塞队列·concurrenthashmap·copyonwritearraylist
微小的鱼2 小时前
Linux的渲染与显示系统链路
android·java·linux
Hhy_11072 小时前
《C++深度解构06》手撕 string —— 从底层内存管理到深浅拷贝彻底吃透
c语言·开发语言·c++·学习·visual studio
starzy19902 小时前
深入理解Scala函数定义:从方法到函数的类型跨越
开发语言·scala