Java可通过定义泛型事件接口Event<T>和线程安全的ConcurrentHashMap+CopyOnWriteArrayList实现轻量级事件总线,支持同步发布、精确类型匹配与Lambda订阅,兼顾解耦、类型安全与并发安全。

Java 中可以通过定义事件接口 + 观察者注册机制,不依赖第三方库实现一个轻量级事件总线。核心是解耦事件发布者与订阅者,利用接口统一事件类型,用泛型保证类型安全,用线程安全的集合管理监听器。
定义统一事件接口
所有事件都实现同一个标记接口(或带泛型的基接口),便于总线统一识别和分发:
- 推荐使用泛型接口
Event<T>,其中T表示事件承载的数据类型,提升编译期类型检查能力 - 也可以用空接口
interface Event {},靠运行时instanceof或 Class 判断类型,更灵活但易出错 - 示例:
<font size="2">public interface Event<T> {<br> T getData();<br>}</font>
实现事件总线核心类
总线负责注册监听器、发布事件、异步/同步分发。关键点:
在 Java 中初始化和管理阿里云 SDK客户端。包括单例模式、线程安全、endpoint 与 region 配置、VPC 终端节点、同步与异步等。
- 用
ConcurrentHashMap<Class<?>, CopyOnWriteArrayList<Consumer<?>>>存储「事件类型 → 监听器列表」映射,兼顾并发安全与遍历时修改安全 - 发布方法根据事件实际类型(
event.getClass())查找对应监听器,避免强依赖继承体系 - 支持泛型推导:监听器可声明为
Consumer<UserCreatedEvent>,总线内部通过反射或类型擦除辅助匹配(简单实现可用Class.isAssignableFrom) - 同步调用即可满足多数场景;如需异步,包裹进
CompletableFuture.runAsync()或自定义线程池
订阅与发布的标准用法
使用者只需面向接口编程,无需感知总线内部细节:
立即学习“Java免费学习笔记(深入)”;
- 订阅:
<font size="2">eventBus.subscribe(UserCreatedEvent.class, event -> {<br> System.out.println("新用户:" + event.getData().getName());<br>});</font> - 发布:
<font size="2">eventBus.publish(new UserCreatedEvent(new User("Alice")));</font> - 监听器可为 lambda、方法引用或任意
Consumer实现,保持轻量和测试友好性
可选增强:事件继承支持与泛型监听
若业务中存在事件继承关系(如 UserEvent ← UserCreatedEvent),可让总线支持向上查找父类型监听器:
- 在
publish()中,不仅查当前类,还遍历其所有超类和接口,依次触发匹配的监听器 - 对泛型事件(如
Event<Order>),监听器写成Consumer<Event<Order>>,总线需提取实际泛型参数做匹配 —— 简单项目可约定监听器用原始类型 + 显式转型,复杂场景建议引入 TypeReference 辅助解析 - 避免过度设计:大多数内部系统只需“精确匹配事件运行时 class”,已足够清晰可控

















