解構EventBus框架(三)本身實現一個EventBus

EventBus實現的思路

定義類:java

  • MyEventBus 事件總線安全

    方法:併發

    • register 註冊
    • unregister 取消註冊
    • post 分發
  • Event 事件異步

  • EventHandler 事件處理器post

如下以兩張圖來表達實現的原理this

註冊:spa

分發:線程

實現EventBus最關鍵的地方是,維護一個事件/處理器的註冊表。在收到註冊請求的時候,將內容加到註冊表中;在收到調用請求的時候,從註冊表中取出對應的處理器並調用。code

動手實現一個EventBus

定義事件-事件處理器:cdn

public class Event<T> {
    private T entity;
    public Event() {
    }
    public Event(T entity) {
        this.entity = entity;
    }
}
複製代碼
public interface EventHandler {
    void handle(Event event);
}
複製代碼

定義EventBus:

//註冊集合
    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 = new ArrayList<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() {
                        eventHandler.handle(event);
                    }
                });
            }
        }
    }

    public void unRegister(Class<? extends Event> event, EventHandler eventHandler) {
        List<EventHandler> list = map.get(event);
        if(list != null) {
            list.remove(eventHandler);
        }
    }
複製代碼

流程調用:

//實例化,並註冊
        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);



        //開戶業務
        User user = new User();
        user.setId("3");
        user.setName("test");

        //實例化事件,併發送
        OpenUserEvent openUserEvent = new OpenUserEvent();
        openUserEvent.setEntity(user);
        myEventBus.post(openUserEvent);
複製代碼

以上咱們實現了一個簡單的EventBus,但這個EventBus還存在如下問題:

  • 線程安全,在註冊和取消註冊的時候,會產生線程安全的問題
  • 註冊時,須要顯示指定事件和事件處理器
  • 事件在分發過程(異步調用)中,若是出現異常,沒法被調用者感知

下章節中,以Google的EventBus爲例,說明如何解決以上問題

相關文章
相關標籤/搜索