java自定义事件处理器极简版:「外卖点餐」场景

一、场景还原(先搞懂业务逻辑)

我们模拟一个极简的外卖系统:

  1. 用户在APP上下单(触发「下单事件」)
  2. 系统自动通知商家接单(事件处理器1)
  3. 系统自动给用户发下单成功短信(事件处理器2)
  4. 系统自动通知骑手准备取餐(事件处理器3)

核心本质某个事情发生了(触发事件),然后自动执行一堆预先设置好的逻辑(事件处理器)


二、代码实现(分步骤拆解)

1. 第一步:定义「事件」------ 告诉系统"发生了什么事"

事件就是一个普通的Java类,用来封装事件的关键信息(比如谁下的单、买了什么)。

java 复制代码
// 外卖订单事件:封装订单的核心信息
class OrderPlacedEvent {
    // 订单ID
    private String orderId;
    // 下单用户
    private String userName;
    // 外卖商品
    private String foodName;

    // 构造方法:创建事件时必须传入核心信息
    public OrderPlacedEvent(String orderId, String userName, String foodName) {
        this.orderId = orderId;
        this.userName = userName;
        this.foodName = foodName;
    }

    // Getter方法:让事件处理器能拿到事件信息
    public String getOrderId() { return orderId; }
    public String getUserName() { return userName; }
    public String getFoodName() { return foodName; }
}

核心作用:把事件的关键数据打包成一个对象,方便后续处理器使用。


2. 第二步:定义「事件处理器接口」------ 约定"事件发生后要做什么"

这是事件驱动的核心契约,规定了所有处理器必须遵守的规则(就像外卖平台规定商家必须在5分钟内接单)。

java 复制代码
// 订单事件处理器接口:所有处理订单事件的逻辑都要实现这个接口
@FunctionalInterface // 标记为函数式接口,方便用Lambda简化
interface OrderEventHandler {
    // 只有一个方法:当订单事件发生时,执行这个方法
    void handleOrderEvent(OrderPlacedEvent event);
}

核心作用:统一所有事件处理器的"行为标准",让系统能无缝对接任意处理器。


3. 第三步:实现「具体的事件处理器」------ 定义"具体要做的事"

我们针对场景中的三个动作,分别写三个处理器:

java 复制代码
// 处理器1:通知商家接单
class MerchantNotifyHandler implements OrderEventHandler {
    @Override
    public void handleOrderEvent(OrderPlacedEvent event) {
        System.out.println("[商家通知] 订单" + event.getOrderId() + "已收到,用户" + event.getUserName() + "点了" + event.getFoodName() + ",请尽快准备!");
    }
}

// 处理器2:给用户发下单成功短信
class UserSmsHandler implements OrderEventHandler {
    @Override
    public void handleOrderEvent(OrderPlacedEvent event) {
        System.out.println("[用户短信] 亲爱的" + event.getUserName() + ",您的订单" + event.getOrderId() + "已提交,我们会尽快为您配送!");
    }
}

// 处理器3:通知骑手准备取餐
class RiderNotifyHandler implements OrderEventHandler {
    @Override
    public void handleOrderEvent(OrderPlacedEvent event) {
        System.out.println("[骑手通知] 订单" + event.getOrderId() + "已生成,请骑手前往商家" + event.getFoodName() + "取餐!");
    }
}

核心作用:把具体业务逻辑和事件触发逻辑彻底解耦,比如以后要加"通知财务记账",只需要新增一个处理器就行,不用改下单的核心代码。


4. 第四步:定义「事件发布器」------ 负责"触发事件并通知所有处理器"

这是整个系统的调度中心,当用户下单时,它会创建事件,并通知所有注册好的处理器。

java 复制代码
// 外卖订单服务:负责接收用户下单请求,触发事件
class OrderService {
    // 用集合保存所有注册的事件处理器(支持多个处理器)
    private List<OrderEventHandler> handlers = new ArrayList<>();

    // 注册处理器:把处理器加入集合(比如商家、用户、骑手的处理器都注册进来)
    public void registerHandler(OrderEventHandler handler) {
        handlers.add(handler);
    }

    // 用户下单:核心方法,触发事件
    public void placeOrder(String orderId, String userName, String foodName) {
        System.out.println("\n=== 用户" + userName + "下单成功 ===");
        // 1. 创建事件对象(封装订单信息)
        OrderPlacedEvent event = new OrderPlacedEvent(orderId, userName, foodName);
        // 2. 通知所有注册的处理器(遍历集合,逐个调用handle方法)
        for (OrderEventHandler handler : handlers) {
            handler.handleOrderEvent(event);
        }
    }
}

核心作用

  • 负责事件的创建和分发,是事件和处理器之间的桥梁
  • 支持动态添加处理器(比如旺季可以临时加一个"通知客服监控超时订单"的处理器)

5. 第五步:测试运行------模拟用户下单
java 复制代码
import java.util.ArrayList;
import java.util.List;

public class SimpleEventDemo {
    public static void main(String[] args) {
        // 1. 创建订单服务(事件发布器)
        OrderService orderService = new OrderService();

        // 2. 注册所有事件处理器(把商家、用户、骑手的处理器都加进去)
        orderService.registerHandler(new MerchantNotifyHandler());
        orderService.registerHandler(new UserSmsHandler());
        orderService.registerHandler(new RiderNotifyHandler());

        // 3. 模拟用户下单(触发事件)
        orderService.placeOrder("ORD20260601001", "张三", "麻辣香锅");
        orderService.placeOrder("ORD20260601002", "李四", "黄焖鸡米饭");
    }
}

运行结果

复制代码
=== 用户张三下单成功 ===
[商家通知] 订单ORD20260601001已收到,用户张三点了麻辣香锅,请尽快准备!
[用户短信] 亲爱的张三,您的订单ORD20260601001已提交,我们会尽快为您配送!
[骑手通知] 订单ORD20260601001已生成,请骑手前往商家麻辣香锅取餐!

=== 用户李四下单成功 ===
[商家通知] 订单ORD20260601002已收到,用户李四点了黄焖鸡米饭,请尽快准备!
[用户短信] 亲爱的李四,您的订单ORD20260601002已提交,我们会尽快为您配送!
[骑手通知] 订单ORD20260601002已生成,请骑手前往商家黄焖鸡米饭取餐!

三、核心思路整理(一张图记住整个流程)

复制代码
用户下单 → OrderService.placeOrder() → 创建OrderPlacedEvent事件 → 遍历所有注册的OrderEventHandler → 逐个调用handleOrderEvent()方法
关键概念提炼(必背)
角色 作用 对应代码类
事件 封装"发生了什么事"的信息 OrderPlacedEvent
事件处理器接口 约定"事件发生后要执行什么"的规范 OrderEventHandler
具体处理器 实现具体的业务逻辑(比如发短信、通知) MerchantNotifyHandler等
事件发布器 触发事件并通知所有处理器 OrderService

四、Java 8 简化优化(用Lambda减少冗余代码)

因为OrderEventHandler是函数式接口,我们可以直接用Lambda替代单独的处理器类,让代码更简洁:

java 复制代码
public class LambdaEventDemo {
    public static void main(String[] args) {
        OrderService orderService = new OrderService();

        // 用Lambda直接注册处理器,不用写单独的类
        orderService.registerHandler(event -> 
            System.out.println("[商家通知] 订单" + event.getOrderId() + "已收到,用户" + event.getUserName() + "点了" + event.getFoodName() + ",请尽快准备!")
        );

        orderService.registerHandler(event -> 
            System.out.println("[用户短信] 亲爱的" + event.getUserName() + ",您的订单" + event.getOrderId() + "已提交,我们会尽快为您配送!")
        );

        orderService.placeOrder("ORD20260601003", "王五", "奶茶");
    }
}

核心优势:对于简单的处理器逻辑,不用再写单独的实现类,直接用Lambda表达式传递,代码量减少一半。

订单事件类封装,

处理器分业务忙。

发布器传消息广,

Lambda简写韵悠长。

相关推荐
J2虾虾1 小时前
Spring AI Alibaba - 智能体作为工具(Agent Tool)
java·人工智能·spring
Hesionberger1 小时前
巧用异或找出唯一数字(多解)
java·数据结构·python·算法·leetcode
铁链鞭策大师1 小时前
javaEE之多线程(2)
java·前端·java-ee
小何code1 小时前
C语言【初阶】第1节,初识C语言
c语言·开发语言
Devin~Y1 小时前
从内容社区到AIGC客服:Spring Boot、Redis、Kafka、K8s、RAG的三轮大厂Java面试对话(附标准答案)
java·spring boot·redis·spring cloud·kafka·kubernetes·micrometer
代码小书生1 小时前
getpass,一个安全输入的 Python 库!
开发语言·python·安全
それども1 小时前
怎么理解TCP的状态
java·网络·网络协议·tcp/ip·dubbo
Xzh04231 小时前
Redis黑马点评 实战复盘与面试高频考点详解
java·数据库·redis·面试
莫陌尛.1 小时前
Fuzzy C-Mean Clustering (FCM)
c语言·开发语言