如何自己实现事件的订阅和发布呢?

1.原理

核心思想是基于发布/订阅模式,用一个共享的数据结构来管理事件和事件监听器。主要功能包括事件订阅、取消订阅、发布事件等功能。

实现思路

  1. 定义事件和监听器接口:首先定义一个 Event 类和一个 EventListener 接口,所有事件和监听器都继承自它们。
  2. 管理订阅关系:使用 Map<Class<? extends Event>, List<EventListener<?>>> 来存储事件类型与监听器的关系。
  3. 发布事件:通过指定事件类型查找所有订阅的监听器,并调用监听器的处理方法。

2.代码工程

Step 1: 定义基础的事件和监听器接口

 

java

代码解读

复制代码

package com.et; // base event public abstract class Event { // some basic filed } package com.et; // event listen interface public interface EventListener<T extends Event> { void onEvent(T event); }

Step 2: 实现 EventBus 类

 

java

代码解读

复制代码

package com.et; import java.util.ArrayList; import java.util.HashMap; import java.util.List; import java.util.Map; public class EventBus { // store event private final Map<Class<? extends Event>, List<EventListener<? extends Event>>> listeners = new HashMap<>(); // Subscribe public <T extends Event> void register(Class<T> eventType, EventListener<T> listener) { listeners.computeIfAbsent(eventType, k -> new ArrayList<>()).add(listener); } // cancel Subscribe public <T extends Event> void unregister(Class<T> eventType, EventListener<T> listener) { List<EventListener<? extends Event>> eventListeners = listeners.get(eventType); if (eventListeners != null) { eventListeners.remove(listener); } } // publish @SuppressWarnings("unchecked") public <T extends Event> void post(T event) { List<EventListener<? extends Event>> eventListeners = listeners.get(event.getClass()); if (eventListeners != null) { for (EventListener<? extends Event> listener : eventListeners) { ((EventListener<T>) listener).onEvent(event); // event forward } } } }

Step 3: 定义自定义事件和监听器

 

java

代码解读

复制代码

package com.et; // UserLoginEvent public class UserLoginEvent extends Event { private final String username; public UserLoginEvent(String username) { this.username = username; } public String getUsername() { return username; } } package com.et; public class UserLoginListener implements EventListener<UserLoginEvent> { @Override public void onEvent(UserLoginEvent event) { System.out.println("User logged in: " + event.getUsername()); } }

代码解释

  1. register 方法:将监听器与事件类型绑定。
  2. post 方法:发布事件,找到所有订阅该事件的监听器并通知它们。
  3. unregister 方法:从事件类型的监听器列表中移除指定监听器。

优化建议

  1. 异步处理:可以使用线程池异步发布事件,提高性能。
  2. 过滤器机制:支持对事件的过滤,以便监听器只接收满足条件的事件。
  3. 事件优先级:可以为监听器定义优先级,根据优先级顺序处理。

这种简单的 EventBus 实现适合单进程内的轻量事件传递。如果需要更复杂的功能(如分布式支持、持久化消息),则可以使用成熟的消息代理系统,如 RabbitMQ 或 Kafka。

以上只是一些关键代码,所有代码请参见下面代码仓库

代码仓库

3.测试

 

java

代码解读

复制代码

package com.et; public class EventBusTest { public static void main(String[] args) { EventBus eventBus = new EventBus(); // register UserLoginListener userLoginListener = new UserLoginListener(); eventBus.register(UserLoginEvent.class, userLoginListener); // publish UserLoginEvent loginEvent = new UserLoginEvent("Alice"); eventBus.post(loginEvent); // unregister eventBus.unregister(UserLoginEvent.class, userLoginListener); eventBus.post(new UserLoginEvent("Bob")); // don't take effort,because the event is unregister } }

运行代码,返回结果

 

sql

代码解读

复制代码

User logged in: Alice

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值