Java事件驱动模型案例

wen java案例 2

本文目录导读:

Java事件驱动模型案例

  1. 基础事件驱动模型(观察者模式)
  2. 事件总线模式(复杂应用)
  3. Swing GUI事件驱动
  4. Spring事件驱动(企业级)
  5. 进阶:异步事件处理
  6. 使用建议

我来为您提供几个Java事件驱动模型的典型案例,从简单到复杂,便于理解和实践。

基础事件驱动模型(观察者模式)

简单的天气事件系统

import java.util.ArrayList;
import java.util.List;
// 1. 事件对象
class WeatherEvent {
    private String type;      // 事件类型
    private String data;      // 事件数据
    private long timestamp;   // 发生时间
    public WeatherEvent(String type, String data) {
        this.type = type;
        this.data = data;
        this.timestamp = System.currentTimeMillis();
    }
    public String getType() { return type; }
    public String getData() { return data; }
    public long getTimestamp() { return timestamp; }
    @Override
    public String toString() {
        return String.format("WeatherEvent[type=%s, data=%s, time=%d]", 
                           type, data, timestamp);
    }
}
// 2. 事件监听器接口
interface WeatherEventListener {
    void onWeatherEvent(WeatherEvent event);
}
// 3. 事件源(主题)
class WeatherStation {
    private List<WeatherEventListener> listeners = new ArrayList<>();
    private String weatherData;
    // 添加监听器
    public void addListener(WeatherEventListener listener) {
        listeners.add(listener);
    }
    // 移除监听器
    public void removeListener(WeatherEventListener listener) {
        listeners.remove(listener);
    }
    // 更新天气并触发事件
    public void updateWeather(String newWeather) {
        this.weatherData = newWeather;
        // 创建事件
        WeatherEvent event = new WeatherEvent("WEATHER_UPDATE", newWeather);
        // 广播事件给所有监听器
        notifyListeners(event);
    }
    // 通知所有监听器
    private void notifyListeners(WeatherEvent event) {
        for (WeatherEventListener listener : listeners) {
            listener.onWeatherEvent(event);
        }
    }
}
// 4. 具体监听器实现
class PhoneDisplay implements WeatherEventListener {
    private String name;
    public PhoneDisplay(String name) {
        this.name = name;
    }
    @Override
    public void onWeatherEvent(WeatherEvent event) {
        System.out.printf("[手机 %s] 收到天气更新: %s%n", 
                         name, event.getData());
        // 根据事件类型做出不同的响应
        if (event.getData().contains("雨")) {
            System.out.println("  → 建议携带雨伞!");
        } else if (event.getData().contains("雪")) {
            System.out.println("  → 注意保暖!");
        }
    }
}
class EmailAlert implements WeatherEventListener {
    private String email;
    public EmailAlert(String email) {
        this.email = email;
    }
    @Override
    public void onWeatherEvent(WeatherEvent event) {
        System.out.printf("[邮件 %s] 发送天气警报: %s%n", 
                         email, event.getData());
        // 可以在此添加发送邮件的逻辑
        System.out.println("  → 邮件已发送");
    }
}
// 5. 测试演示
public class WeatherEventDemo {
    public static void main(String[] args) {
        System.out.println("=== 天气事件驱动系统演示 ===\n");
        // 创建天气站(事件源)
        WeatherStation station = new WeatherStation();
        // 创建监听器
        PhoneDisplay phone1 = new PhoneDisplay("iPhone");
        PhoneDisplay phone2 = new PhoneDisplay("Android");
        EmailAlert email = new EmailAlert("user@example.com");
        // 订阅事件
        station.addListener(phone1);
        station.addListener(phone2);
        station.addListener(email);
        // 触发天气更新事件
        System.out.println("--- 第一次天气更新 ---");
        station.updateWeather("晴,温度28°C");
        System.out.println("\n--- 第二次天气更新 ---");
        station.updateWeather("中雨,温度20°C");
        // 移除一个监听器
        System.out.println("\n--- 移除iPhone监听器后 ---");
        station.removeListener(phone1);
        station.updateWeather("多云,温度25°C");
    }
}

事件总线模式(复杂应用)

通用事件总线实现

import java.util.*;
import java.util.concurrent.*;
// 事件类型枚举
enum EventType {
    USER_LOGIN,     // 用户登录
    USER_LOGOUT,    // 用户登出
    ORDER_CREATED,  // 订单创建
    ORDER_PAID,     // 订单支付
    ORDER_SHIPPED,  // 订单发货
    SYSTEM_ERROR    // 系统错误
}
// 事件类
class Event {
    private EventType type;
    private String payload;
    private long timestamp;
    public Event(EventType type, String payload) {
        this.type = type;
        this.payload = payload;
        this.timestamp = System.currentTimeMillis();
    }
    public EventType getType() { return type; }
    public String getPayload() { return payload; }
    public long getTimestamp() { return timestamp; }
}
// 事件监听器接口
interface EventListener {
    void onEvent(Event event);
    EventType[] getSubscribedTypes();
}
// 事件总线(单例)
class EventBus {
    private static EventBus instance = new EventBus();
    private Map<EventType, List<EventListener>> listeners = new ConcurrentHashMap<>();
    private ExecutorService executor = Executors.newCachedThreadPool();
    private EventBus() {
        // 初始化所有事件类型
        for (EventType type : EventType.values()) {
            listeners.put(type, new CopyOnWriteArrayList<>());
        }
    }
    public static EventBus getInstance() {
        return instance;
    }
    // 订阅事件
    public void subscribe(EventListener listener) {
        for (EventType type : listener.getSubscribedTypes()) {
            listeners.get(type).add(listener);
        }
        System.out.printf("[EventBus] Listener %s 订阅了 %d 种事件%n",
                         listener.getClass().getSimpleName(),
                         listener.getSubscribedTypes().length);
    }
    // 取消订阅
    public void unsubscribe(EventListener listener) {
        for (EventType type : listener.getSubscribedTypes()) {
            listeners.get(type).remove(listener);
        }
        System.out.printf("[EventBus] Listener %s 取消了订阅%n",
                         listener.getClass().getSimpleName());
    }
    // 发布事件
    public void publish(Event event) {
        List<EventListener> eventListeners = listeners.get(event.getType());
        System.out.printf("[EventBus] 发布事件: type=%s, payload=%s%n",
                         event.getType(), event.getPayload());
        // 异步处理事件,提高性能
        for (EventListener listener : eventListeners) {
            executor.submit(() -> listener.onEvent(event));
        }
    }
    // 关闭线程池
    public void shutdown() {
        executor.shutdown();
    }
}
// 用户服务监听器
class UserService implements EventListener {
    @Override
    public void onEvent(Event event) {
        System.out.println("  [用户服务] 处理登录事件: " + event.getPayload());
        // 模拟耗时操作
        try {
            Thread.sleep(100);
        } catch (InterruptedException e) {
            Thread.currentThread().interrupt();
        }
        System.out.println("  [用户服务] 登录处理完成");
    }
    @Override
    public EventType[] getSubscribedTypes() {
        return new EventType[]{EventType.USER_LOGIN, EventType.USER_LOGOUT};
    }
}
// 订单服务监听器
class OrderService implements EventListener {
    @Override
    public void onEvent(Event event) {
        System.out.println("  [订单服务] 处理订单事件: " + event.getPayload());
        switch (event.getType()) {
            case ORDER_CREATED:
                System.out.println("  → 更新订单状态为待支付");
                break;
            case ORDER_PAID:
                System.out.println("  → 通知仓库准备发货");
                break;
            case ORDER_SHIPPED:
                System.out.println("  → 发送物流信息给用户");
                break;
        }
    }
    @Override
    public EventType[] getSubscribedTypes() {
        return new EventType[]{
            EventType.ORDER_CREATED,
            EventType.ORDER_PAID,
            EventType.ORDER_SHIPPED
        };
    }
}
// 日志服务监听器
class LogService implements EventListener {
    @Override
    public void onEvent(Event event) {
        // 日志记录所有事件
        System.out.printf("  [日志服务] 记录日志: type=%s, payload=%s, timestamp=%d%n",
                         event.getType(), event.getPayload(), event.getTimestamp());
    }
    @Override
    public EventType[] getSubscribedTypes() {
        return EventType.values(); // 订阅所有事件
    }
}
// 测试事件总线
public class EventBusDemo {
    public static void main(String[] args) throws InterruptedException {
        System.out.println("=== 事件总线驱动模型演示 ===\n");
        EventBus eventBus = EventBus.getInstance();
        // 创建并注册监听器
        UserService userService = new UserService();
        OrderService orderService = new OrderService();
        LogService logService = new LogService();
        eventBus.subscribe(userService);
        eventBus.subscribe(orderService);
        eventBus.subscribe(logService);
        System.out.println("\n--- 模拟业务流程 ---\n");
        // 模拟用户登录
        eventBus.publish(new Event(EventType.USER_LOGIN, "user@example.com"));
        Thread.sleep(200); // 等待异步处理
        // 模拟创建订单
        eventBus.publish(new Event(EventType.ORDER_CREATED, "订单号: 2024001"));
        Thread.sleep(200);
        // 模拟支付
        eventBus.publish(new Event(EventType.ORDER_PAID, "订单号: 2024001, 金额: $99.9"));
        Thread.sleep(200);
        // 模拟发货
        eventBus.publish(new Event(EventType.ORDER_SHIPPED, "订单号: 2024001, 物流号: SF123456"));
        Thread.sleep(200);
        // 模拟用户登出
        eventBus.publish(new Event(EventType.USER_LOGOUT, "user@example.com"));
        // 关闭事件总线
        eventBus.shutdown();
    }
}

Swing GUI事件驱动

import javax.swing.*;
import java.awt.*;
import java.awt.event.*;
public class GuiEventDemo {
    public static void main(String[] args) {
        SwingUtilities.invokeLater(() -> {
            createAndShowGUI();
        });
    }
    private static void createAndShowGUI() {
        JFrame frame = new JFrame("GUI事件驱动示例");
        frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
        frame.setLayout(new GridLayout(3, 1, 10, 10));
        // 创建组件
        JTextField textField = new JTextField(20);
        JButton button = new JButton("点击我");
        JTextArea textArea = new JTextArea(5, 20);
        textArea.setEditable(false);
        // 添加事件监听器
        // 1. 按钮点击事件
        button.addActionListener(new ActionListener() {
            @Override
            public void actionPerformed(ActionEvent e) {
                String text = textField.getText();
                textArea.append("按钮被点击,输入内容: " + text + "\n");
            }
        });
        // 2. 文本框键盘事件
        textField.addKeyListener(new KeyAdapter() {
            @Override
            public void keyPressed(KeyEvent e) {
                if (e.getKeyCode() == KeyEvent.VK_ENTER) {
                    textArea.append("按下回车键\n");
                }
            }
        });
        // 3. 鼠标事件
        button.addMouseListener(new MouseAdapter() {
            @Override
            public void mouseEntered(MouseEvent e) {
                button.setBackground(Color.GREEN);
                textArea.append("鼠标进入按钮区域\n");
            }
            @Override
            public void mouseExited(MouseEvent e) {
                button.setBackground(null);
                textArea.append("鼠标离开按钮区域\n");
            }
        });
        // 布局
        frame.add(textField);
        frame.add(button);
        frame.add(new JScrollPane(textArea));
        frame.pack();
        frame.setLocationRelativeTo(null);
        frame.setVisible(true);
    }
}

Spring事件驱动(企业级)

import org.springframework.context.ApplicationEvent;
import org.springframework.context.ApplicationListener;
import org.springframework.context.annotation.AnnotationConfigApplicationContext;
import org.springframework.context.annotation.ComponentScan;
import org.springframework.context.annotation.Configuration;
import org.springframework.stereotype.Component;
import java.time.LocalDateTime;
// Spring配置类
@Configuration
@ComponentScan
class AppConfig {}
// 自定义事件
class OrderEvent extends ApplicationEvent {
    private Long orderId;
    private String orderStatus;
    private LocalDateTime eventTime;
    public OrderEvent(Object source, Long orderId, String orderStatus) {
        super(source);
        this.orderId = orderId;
        this.orderStatus = orderStatus;
        this.eventTime = LocalDateTime.now();
    }
    public Long getOrderId() { return orderId; }
    public String getOrderStatus() { return orderStatus; }
    public LocalDateTime getEventTime() { return eventTime; }
}
// 事件监听器 - 发送邮件
@Component
class EmailNotificationListener implements ApplicationListener<OrderEvent> {
    @Override
    public void onApplicationEvent(OrderEvent event) {
        System.out.println("[邮件监听器] 订单 #" + event.getOrderId() + 
                          " 状态更新为: " + event.getOrderStatus() + 
                          " ,发送通知邮件");
    }
}
// 事件监听器 - 更新库存
@Component
class InventoryUpdateListener implements ApplicationListener<OrderEvent> {
    @Override
    public void onApplicationEvent(OrderEvent event) {
        if ("PAID".equals(event.getOrderStatus())) {
            System.out.println("[库存监听器] 订单 #" + event.getOrderId() + 
                             " 已支付,扣减库存");
        }
    }
}
// 事件监听器 - 生成报表
@Component
class ReportListener implements ApplicationListener<OrderEvent> {
    @Override
    public void onApplicationEvent(OrderEvent event) {
        if ("COMPLETED".equals(event.getOrderStatus())) {
            System.out.println("[报表监听器] 订单 #" + event.getOrderId() + 
                             " 已完成,生成销售报表");
        }
    }
}
// 测试类
public class SpringEventDemo {
    public static void main(String[] args) {
        System.out.println("=== Spring 事件驱动模型演示 ===\n");
        // 创建Spring上下文
        AnnotationConfigApplicationContext context = 
            new AnnotationConfigApplicationContext(AppConfig.class);
        // 发布不同状态的事件
        System.out.println("--- 订单创建 ---");
        context.publishEvent(new OrderEvent(context, 1L, "CREATED"));
        System.out.println("\n--- 订单支付 ---");
        context.publishEvent(new OrderEvent(context, 2L, "PAID"));
        System.out.println("\n--- 订单完成 ---");
        context.publishEvent(new OrderEvent(context, 3L, "COMPLETED"));
        System.out.println("\n--- 事件顺序执行总结 ---");
        context.close();
    }
}

进阶:异步事件处理

import java.util.concurrent.*;
import java.util.concurrent.atomic.*;
class AsyncEventExample {
    // 基本的异步事件处理器
    static class AsyncEventProcessor {
        private ExecutorService executor = Executors.newFixedThreadPool(4);
        private ConcurrentLinkedQueue<String> eventQueue = new ConcurrentLinkedQueue<>();
        private AtomicInteger processedCount = new AtomicInteger();
        public void processEvents() {
            // 异步处理事件
            executor.submit(() -> {
                while (true) {
                    String event = eventQueue.poll();
                    if (event != null) {
                        handleEvent(event);
                    } else {
                        // 队列为空时短暂休眠
                        try {
                            Thread.sleep(50);
                        } catch (InterruptedException e) {
                            Thread.currentThread().interrupt();
                            break;
                        }
                    }
                }
            });
        }
        private void handleEvent(String event) {
            System.out.printf("处理事件: %s (线程: %s)%n", 
                            event, Thread.currentThread().getName());
            // 模拟处理耗时
            try {
                Thread.sleep(100);
            } catch (InterruptedException e) {
                Thread.currentThread().interrupt();
            }
            processedCount.incrementAndGet();
            System.out.printf("事件 %s 处理完成,总计处理 %d 个事件%n",
                            event, processedCount.get());
        }
        public void addEvent(String event) {
            eventQueue.add(event);
            System.out.printf("添加事件: %s (队列大小: %d)%n",
                            event, eventQueue.size());
        }
        public void shutdown() {
            executor.shutdown();
        }
    }
    public static void main(String[] args) throws InterruptedException {
        System.out.println("=== 异步事件处理示例 ===\n");
        AsyncEventProcessor processor = new AsyncEventProcessor();
        processor.processEvents();
        // 添加多个事件
        for (int i = 1; i <= 10; i++) {
            processor.addEvent("事件-" + i);
        }
        // 等待处理完成
        Thread.sleep(2000);
        processor.shutdown();
    }
}

使用建议

  1. 选择合适模式

    • 简单场景:使用观察者模式
    • 复杂系统:使用事件总线
    • 企业应用:使用Spring事件
  2. 性能优化

    • 使用异步处理
    • 合理使用线程池
    • 考虑事件队列
  3. 可靠性

    • 处理事件异常
    • 确保事件顺序(如需要)
    • 实现重试机制
  4. 设计原则

    • 事件解耦
    • 单一职责
    • 观察者模式与发布订阅模式区分

这些示例涵盖了从基础到高级的事件驱动模型,每个都可以直接运行和扩展,建议从简单的开始,逐步理解事件驱动的精髓。

抱歉,评论功能暂时关闭!