EventBus implementation ideas
Define the class:
-
MyEventBus Event bus
Methods:
- Register to register
- Unregister cancels registration
- Post distribution
-
The Event Event
-
EventHandler EventHandler
The following two diagrams illustrate the implementation principle
Registration:
Distribution:
The most critical aspect of implementing EventBus is maintaining an event/handler registry. Add content to the registry when a registration request is received; When a call request is received, the corresponding handler is fetched from the registry and invoked.
Start implementing an EventBus
Define event – event handler:
public class Event<T> {
private T entity;
public Event(a) {}public Event(T entity) {
this.entity = entity; }}Copy the code
public interface EventHandler {
void handle(Event event);
}
Copy the code
Define the EventBus:
// Register the collection
private Map<Class<? extends Event>, List<EventHandler>> map = new HashMap<Class<? extends Event>, List<EventHandler>>();
private Executor executor = Executors.newFixedThreadPool(10);
public void register(Class<? extends Event> event, EventHandler eventHandler) {
List<EventHandler> list = map.get(event);
if(list ! =null) {
list.add(eventHandler);
} else {
list = newArrayList<EventHandler>(); list.add(eventHandler); map.put(event,list); }}public void post(final Event event) {
List<EventHandler> list = map.get(event.getClass());
if(list ! =null) {
for (final EventHandler eventHandler : list) {
executor.execute(new Runnable() {
public void run(a) { eventHandler.handle(event); }}); }}}public void unRegister(Class<? extends Event> event, EventHandler eventHandler) {
List<EventHandler> list = map.get(event);
if(list ! =null) { list.remove(eventHandler); }}Copy the code
Process invocation:
// instantiate and register
MyEventBus myEventBus = new MyEventBus();
EventHandler handler = new EventHandler() {
public void handle(Event event) { User user = (User) event.getEntity(); System.out.println(user.getId()); }}; myEventBus.register(OpenUserEvent.class,handler);// Account opening
User user = new User();
user.setId("3");
user.setName("test");
// Instantiate the event and send it
OpenUserEvent openUserEvent = new OpenUserEvent();
openUserEvent.setEntity(user);
myEventBus.post(openUserEvent);
Copy the code
We implemented a simple EventBus, but the EventBus had the following problems:
- Thread-safety. Thread-safety issues arise during registration and deregistration
- When registered, the specified event and event handler need to be displayed
- Events in distribution (asynchronous invocation) cannot be sensed by the caller if an exception occurs
In the following section, Google EventBus is used as an example to explain how to solve the above problems