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);
}
}