Nacos server事件分发EventDispatcher代码小结

EventDispatcher类,作为事件分发器。

AbstractEventListener静态内部抽象类,继承该类后实例化的子类,将在该类中的构造方法被注册到EventDispatcher中,这一点以前我没有想到,挺好的写法,设计模式是监听器模式,通过事件调用具体事件的监听类。对于Spring监听器的实现也是类似,只不过spring监听器将事件作为参数与监听器绑定,通过监听器轮询反射获取参数类型进行比对,而nacos事件分发监听是直接通过监听器与事件类进行成员变量的绑定,注册监听事件的过程有点绕,过程总结如下:

实例化子类监听器-》注册子类监听器,注册过程同时要调用子类监听器的interest方法,返回事件类型,将事件类型与监听器进行多对一的注册Entry入口中

 /**
     * add event listener
     */
    static public void addEventListener(AbstractEventListener listener) {
        for (Class<? extends Event> type : listener.interest()) {
            getEntry(type).listeners.addIfAbsent(listener);
        }
    }

       

Entry类的成员变量:
        final Class<? extends Event> eventType;
        final CopyOnWriteArrayList<AbstractEventListener> listeners;

static Entry getEntry(Class<? extends Event> eventType) {
        for (; ; ) {
            for (Entry entry : LISTENER_HUB) {
                if (entry.eventType == eventType) {
                    return entry;
                }
            }

            Entry tmp = new Entry(eventType);
            /**
             *  false means already exists
             */
            if (LISTENER_HUB.addIfAbsent(tmp)) {
                return tmp;
            }
        }
    }


使用过程通过调用:

EventDispatcher.fireEvent(new ConfigDataChangeEvent(false, dataId, group, tenant, time.getTime()));

/**
     * fire event, notify listeners.
     */
    static public void fireEvent(Event event) {
        if (null == event) {
            throw new IllegalArgumentException();
        }

        for (AbstractEventListener listener : getEntry(event.getClass()).listeners) {
            try {
                listener.onEvent(event);
            } catch (Exception e) {
                log.error(e.toString(), e);
            }
        }
    }

完整事件分配的代码:

 
public class EventDispatcher {

    /**
     * add event listener
     */
    static public void addEventListener(AbstractEventListener listener) {
        for (Class<? extends Event> type : listener.interest()) {
            getEntry(type).listeners.addIfAbsent(listener);
        }
    }

    /**
     * fire event, notify listeners.
     */
    static public void fireEvent(Event event) {
        if (null == event) {
            throw new IllegalArgumentException();
        }

        for (AbstractEventListener listener : getEntry(event.getClass()).listeners) {
            try {
                listener.onEvent(event);
            } catch (Exception e) {
                log.error(e.toString(), e);
            }
        }
    }

    /**
     * For only test purpose
     */
    static public void clear() {
        LISTENER_HUB.clear();
    }

    /**
     * get event listener for eventType. Add Entry if not exist.
     */
    static Entry getEntry(Class<? extends Event> eventType) {
        for (; ; ) {
            for (Entry entry : LISTENER_HUB) {
                if (entry.eventType == eventType) {
                    return entry;
                }
            }

            Entry tmp = new Entry(eventType);
            /**
             *  false means already exists
             */
            if (LISTENER_HUB.addIfAbsent(tmp)) {
                return tmp;
            }
        }
    }

    static private class Entry {
        final Class<? extends Event> eventType;
        final CopyOnWriteArrayList<AbstractEventListener> listeners;

        Entry(Class<? extends Event> type) {
            eventType = type;
            listeners = new CopyOnWriteArrayList<AbstractEventListener>();
        }

        @Override
        public boolean equals(Object obj) {
            if (null == obj || obj.getClass() != getClass()) {
                return false;
            }
            if (this == obj) {
                return true;
            }
            return eventType == ((Entry)obj).eventType;
        }

        @Override
        public int hashCode() {
            return super.hashCode();
        }

    }

    static private final Logger log = LoggerFactory.getLogger(EventDispatcher.class);

    static final CopyOnWriteArrayList<Entry> LISTENER_HUB = new CopyOnWriteArrayList<Entry>();

    public interface Event {
    }

    static public abstract class AbstractEventListener {

        public AbstractEventListener() {
            /**
             * automatic register
             */
            EventDispatcher.addEventListener(this);
        }

        /**
         * 感兴趣的事件列表
         *
         * @return event list
         */
        abstract public List<Class<? extends Event>> interest();

        /**
         * 处理事件
         *
         * @param event event
         */
        abstract public void onEvent(Event event);
    }

}

 

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章