在java开发中,要实现事件驱动,即当发生按特定事件时,通知关联方以便作出改变,有三种方案:
一、分析对比
1、观察者模式;
2、Redis 订阅机制;
3、专业版 MQ。
下面逐一进行介绍并总结其各自的适用场景。
1. Java 观察者模式(Observer Pattern)
这是设计模式层面的一种行为型模式,核心是实现「一对多」的对象依赖关系:当一个对象(被观察者 / Subject)状态发生变化时,所有依赖它的对象(观察者 / Observer)会被自动通知并更新。
核心特点:
- 内存内同步通信:观察者和被观察者都运行在同一个 JVM 进程内,通知是同步的(被观察者通知完所有观察者后,自身方法才会返回)。
- 耦合度低:基于接口编程(Subject/Observer 接口),观察者和被观察者只需依赖接口,无需知道对方具体实现。
- 无持久化 / 重试:通知过程仅在内存中完成,若观察者处理失败,被观察者不会重试,也无消息持久化能力。
简单代码示例:
import java.util.Observable; import java.util.Observer; // 被观察者:发布消息的对象 class MessageSubject extends Observable { public void publishMessage(String msg) { // 标记状态变化 setChanged(); // 通知所有观察者 notifyObservers(msg); } } // 观察者1:接收并处理消息 class MessageObserver1 implements Observer { @Override public void update(Observable o, Object arg) { System.out.println("观察者1收到消息:" + arg); } } // 观察者2:接收并处理消息 class MessageObserver2 implements Observer { @Override public void update(Observable o, Object arg) { System.out.println("观察者2收到消息:" + arg); } } // 测试 public class ObserverDemo { public static void main(String[] args) { MessageSubject subject = new MessageSubject(); // 注册观察者 subject.addObserver(new MessageObserver1()); subject.addObserver(new MessageObserver2()); // 发布消息 subject.publishMessage("Hello 观察者模式"); } }输出:
观察者2收到消息:Hello 观察者模式
观察者1收到消息:Hello 观察者模式
从中可以看出消息的处理顺序是随机的。
2. Redis 订阅 / 发布机制(Pub/Sub)
Redis 提供的轻量级消息通信机制,核心是「频道(Channel)」:发布者向指定频道发送消息,所有订阅该频道的客户端都会收到消息。
核心特点:
- 跨进程 / 跨机器通信:基于 Redis 服务端中转,支持不同进程、不同机器的客户端通信。
- 无持久化 / 无确认机制:消息发送后若没有订阅者,消息直接丢失;Redis 不会记录消息,也不保证订阅者一定收到(如客户端断连)。
- 轻量简单:无需复杂配置,适合低可靠性要求的场景(如实时通知、状态同步)。
简单使用示例(Redis CLI):
# 终端1:订阅频道 "news" redis-cli SUBSCRIBE news # 终端2:向频道 "news" 发布消息 redis-cli PUBLISH news "Redis 发布订阅测试" # 终端1 会收到: # "message" # "news" # "Redis 发布订阅测试"3. 专业版 MQ(以 RabbitMQ 为例)
RabbitMQ 是基于 AMQP 协议的重量级消息中间件,核心是「消息队列」:消息由生产者发送到队列,消费者从队列获取消息,中间件提供完善的消息管控能力。
核心特点:
- 高可靠性:支持消息持久化(磁盘存储)、消息确认(ACK)、重试机制,确保消息不丢失。
- 异步解耦:生产者发送消息后无需等待消费者处理,中间件缓存消息,消费者按需消费。
- 丰富的路由策略:支持交换机(Direct/Fanout/Topic)、队列绑定,可实现复杂的消息路由(如按规则分发给不同消费者)。
- 集群 / 高可用:支持集群部署,避免单点故障,适合高并发、高可靠性要求的生产环境。
简单代码示例(Java + RabbitMQ):
import com.rabbitmq.client.Channel; import com.rabbitmq.client.Connection; import com.rabbitmq.client.ConnectionFactory; import com.rabbitmq.client.DeliverCallback; public class RabbitMQDemo { private static final String QUEUE_NAME = "test_queue"; // 生产者:发送消息 public static void sendMessage() throws Exception { ConnectionFactory factory = new ConnectionFactory(); factory.setHost("localhost"); // Redis 服务地址 try (Connection connection = factory.newConnection(); Channel channel = connection.createChannel()) { // 声明队列(持久化) channel.queueDeclare(QUEUE_NAME, true, false, false, null); String message = "RabbitMQ 测试消息"; // 发送消息 channel.basicPublish("", QUEUE_NAME, null, message.getBytes()); System.out.println("生产者发送消息:" + message); } } // 消费者:接收消息 public static void receiveMessage() throws Exception { ConnectionFactory factory = new ConnectionFactory(); factory.setHost("localhost"); Connection connection = factory.newConnection(); Channel channel = connection.createChannel(); channel.queueDeclare(QUEUE_NAME, true, false, false, null); System.out.println("消费者等待接收消息..."); // 消息回调处理 DeliverCallback deliverCallback = (consumerTag, delivery) -> { String message = new String(delivery.getBody(), "UTF-8"); System.out.println("消费者收到消息:" + message); // 手动确认消息已处理(确保不重复消费) channel.basicAck(delivery.getEnvelope().getDeliveryTag(), false); }; // 消费消息(关闭自动确认) channel.basicConsume(QUEUE_NAME, false, deliverCallback, consumerTag -> {}); } public static void main(String[] args) throws Exception { // 启动生产者 sendMessage(); // 启动消费者 receiveMessage(); } }二、三者核心对比
| 维度 | Java 观察者模式 | Redis 订阅 / 发布 | RabbitMQ(专业 MQ) |
|---|---|---|---|
| 通信范围 | 单 JVM 进程内 | 跨进程 / 跨机器 | 跨进程 / 跨机器 |
| 可靠性 | 无重试 / 无持久化 | 无重试 / 无持久化 | 有重试 / 有持久化 / ACK |
| 耦合度 | 低(接口解耦) | 极低(Redis 中转) | 极低(队列解耦) |
| 性能 | 极高(内存通信) | 高(Redis 轻量) | 中(功能复杂) |
| 适用场景 | 单进程内状态通知 | 轻量实时通知、低可靠 | 高并发、高可靠业务场景 |
| 核心定位 | 设计模式(代码层面) | 轻量消息工具 | 企业级消息中间件 |
三、总结
- Java 观察者模式是「代码层面」的解耦方案,仅适用于单进程内的消息通知,无跨进程能力;
- Redis 订阅机制是「轻量跨进程」的消息工具,适合低可靠性要求的实时通知,不适合核心业务;
- RabbitMQ 等专业 MQ是「企业级」的消息中间件,提供完善的可靠性保障,是核心业务异步解耦、削峰填谷的首选。