事件监听
package com.example.observer.customization.event; import java.util.EventObject; /** * 事件的抽象 */ public abstract class AppEvent extends EventObject { /** * Constructs a prototypical Event. * * @param source The object on which the Event initially occurred. * @throws IllegalArgumentException if source is null. */ public AppEvent(Object source) { super(source); } }
package com.example.observer.customization.listener; import com.example.observer.customization.event.AppEvent; import java.lang.reflect.ParameterizedType; import java.lang.reflect.Type; import java.util.EventListener; /** * 应用事件监听器接口 */ public interface AppListener<E extends AppEvent> extends EventListener { void onAppEvent(E event); default boolean supportEventType(Class eventType){ Type[] genericInterfaces = this.getClass().getGenericInterfaces(); if (genericInterfaces.getClass().isAssignableFrom(ParameterizedType[].class)) { for (Type genericInterface : genericInterfaces) { ParameterizedType parameterizedType = (ParameterizedType) genericInterface; Type[] actualTypeArguments = parameterizedType.getActualTypeArguments(); Type type = actualTypeArguments[0]; if (type instanceof Class) { Class clazz = (Class) type; return clazz==eventType; } } } return false; } default boolean supportSourceType(Class sourceType) { return true; } }
package com.example.observer.customization.multicaster; import com.example.observer.customization.event.AppEvent; import com.example.observer.customization.listener.AppListener; /** * 事件广播器 */ public interface AppEventMulticaster { /** * 添加监听器 * @param listener */ void addAppListener(AppListener<?> listener); /** * 广播事件给对应的监听器 * @param event */ void multicasterEvent(AppEvent event); }
package com.example.observer.customization.multicaster; import com.example.observer.customization.event.AppEvent; import com.example.observer.customization.listener.AppListener; import java.util.*; import java.util.concurrent.ConcurrentHashMap; public abstract class AbstractAppEventMulticaster implements AppEventMulticaster { private final ListenerHelper defaultHelper = new ListenerHelper(); protected final Map<ListenerCacheKey,ListenerHelper> helperCache = new ConcurrentHashMap(64); @Override public void addAppListener(AppListener<?> listener) { defaultHelper.appListeners.add(listener); } /** * 根据事件返回对应的监听器集合 * @param event * @return */ protected Collection<AppListener<?>> getAppListeners(AppEvent event){ Object source = event.getSource(); Class sourceType = source==null? null:source.getClass(); ListenerCacheKey cacheKey = new ListenerCacheKey(event.getClass(),sourceType); ListenerHelper helper = helperCache.get(cacheKey); if (helper!=null) { return helper.getAppListeners(); }else { // search defaultHelper helper = new ListenerHelper(); Collection<AppListener<?>> listeners = getAppListeners(event.getClass(),sourceType,helper); helperCache.put(cacheKey,helper); return listeners; } } /** * 根据 eventType sourceType 从 defaultHelper中找到对应的listener集合,填充给helper并且返回 * @param eventType * @param sourceType * @param helper * @return */ private Collection<AppListener<?>> getAppListeners(Class eventType, Class sourceType, ListenerHelper helper) { Collection<AppListener<? extends AppEvent>> allListeners = defaultHelper.getAppListeners(); List<AppListener<?>> returns = new ArrayList<>(); for (AppListener<?> listener : allListeners) { if(supportEvent(listener,eventType,sourceType)) { if (helper!=null) { helper.appListeners.add(listener); } returns.add(listener); } } return returns; } private boolean supportEvent(AppListener<?> listener, Class eventType, Class sourceType) { return listener.supportEventType(eventType) && listener.supportSourceType(sourceType); } private class ListenerCacheKey { private final Class eventType; private final Class sourceType; public ListenerCacheKey(Class eventType,Class sourceType) { this.eventType = eventType; this.sourceType = sourceType; } @Override public boolean equals(Object o) { if (this == o) return true; if (o == null || getClass() != o.getClass()) return false; ListenerCacheKey cacheKey = (ListenerCacheKey) o; return Objects.equals(eventType, cacheKey.eventType) && Objects.equals(sourceType, cacheKey.sourceType); } @Override public int hashCode() { return Objects.hash(eventType, sourceType); } @Override public String toString() { return "ListenerCacheKey{" + "eventType=" + eventType + ", sourceType=" + sourceType + '}'; } } private class ListenerHelper { private final Set<AppListener<? extends AppEvent>> appListeners = new LinkedHashSet<>(); public Collection<AppListener<? extends AppEvent>> getAppListeners() { List<AppListener<? extends AppEvent>> allListeners = new ArrayList<>(appListeners.size()); allListeners.addAll(appListeners); return allListeners; } } }
package com.example.observer.customization.multicaster; import com.example.observer.customization.event.AppEvent; import com.example.observer.customization.listener.AppListener; import java.util.concurrent.Executor; import java.util.concurrent.LinkedBlockingQueue; import java.util.concurrent.ThreadPoolExecutor; import java.util.concurrent.TimeUnit; public class SimpleAppEventMulticaster extends AbstractAppEventMulticaster{ private Executor executor = new ThreadPoolExecutor( 5, 10, 60, TimeUnit.SECONDS, new LinkedBlockingQueue<>(100) ); @Override public void multicasterEvent(AppEvent event) { // 1,找到对该事件感兴趣的监听器, 2,依次回调 for (AppListener listener : getAppListeners(event)) { if (executor!=null) { executor.execute(()->{ invokeListener(listener,event); }); }else { invokeListener(listener,event); } } } private void invokeListener(AppListener listener, AppEvent event) { try { listener.onAppEvent(event); } catch (Exception e) { e.printStackTrace(); //////////.........不同的异常处理机制 } } }
package com.example.observer.customization.publisher; import com.example.observer.customization.event.AppEvent; public interface AppEventPublisher { void publishEvent(AppEvent event); }
package com.example.observer.customization.publisher; import com.example.observer.customization.event.AppEvent; import com.example.observer.customization.multicaster.AppEventMulticaster; public class DefaultAppEventPublisher implements AppEventPublisher{ private AppEventMulticaster appEventMulticaster; public void setAppEventMulticaster (AppEventMulticaster appEventMulticaster) { this.appEventMulticaster = appEventMulticaster; } @Override public void publishEvent(AppEvent event) { appEventMulticaster.multicasterEvent(event); } }
=======================================
package com.example.observer.event; import com.example.observer.customization.event.AppEvent; public class ConfigAddEvent extends AppEvent { private Integer id; /** * Constructs a prototypical Event. * * @param source The object on which the Event initially occurred. * @throws IllegalArgumentException if source is null. */ public ConfigAddEvent(Object source,Integer id) { super(source); this.id = id; } }
package com.example.observer.event; import com.example.observer.customization.event.AppEvent; public class ConfigDeleteEvent extends AppEvent { /** * Constructs a prototypical Event. * * @param source The object on which the Event initially occurred. * @throws IllegalArgumentException if source is null. */ public ConfigDeleteEvent(Object source) { super(source); } }
package com.example.observer.listener; import com.example.observer.customization.listener.AppListener; import com.example.observer.event.ConfigAddEvent; public class ConfigAddListener implements AppListener<ConfigAddEvent> { @Override public void onAppEvent(ConfigAddEvent event) { System.out.println("ConfigAddListener----" + Thread.currentThread().getName() + ",event=" + event); } }
package com.example.observer.listener; import com.example.observer.customization.listener.AppListener; import com.example.observer.event.ConfigAddEvent; public class ConfigAddListener2 implements AppListener<ConfigAddEvent> { @Override public void onAppEvent(ConfigAddEvent event) { System.out.println("ConfigAddListener2----" + Thread.currentThread().getName() + ",event=" + event); } }
package com.example.observer.listener; import com.example.observer.customization.listener.AppListener; import com.example.observer.event.ConfigDeleteEvent; public class ConfigDeleteListener implements AppListener<ConfigDeleteEvent> { @Override public void onAppEvent(ConfigDeleteEvent event) { System.out.println("ConfigDeleteListener---" + Thread.currentThread().getName() + ",event=" + event); } }
package com.example.observer; import com.example.observer.customization.multicaster.AppEventMulticaster; import com.example.observer.customization.multicaster.SimpleAppEventMulticaster; import com.example.observer.customization.publisher.DefaultAppEventPublisher; import com.example.observer.entity.Config; import com.example.observer.event.ConfigAddEvent; import com.example.observer.event.ConfigDeleteEvent; import com.example.observer.listener.ConfigAddListener; import com.example.observer.listener.ConfigAddListener2; import com.example.observer.listener.ConfigDeleteListener; public class ObserverTest { public static void main(String[] args) { // multicaster AppEventMulticaster multicaster = new SimpleAppEventMulticaster(); //add listener multicaster.addAppListener(new ConfigAddListener()); multicaster.addAppListener(new ConfigAddListener2()); multicaster.addAppListener(new ConfigDeleteListener()); // publisher DefaultAppEventPublisher publisher = new DefaultAppEventPublisher(); publisher.setAppEventMulticaster(multicaster); // publish event publisher.publishEvent(new ConfigAddEvent(new Config(12,"g1","n1","add1"),12)); System.out.println("业务继续执行"); publisher.publishEvent(new ConfigDeleteEvent(new Config(13,"g1","n1","del13"))); System.out.println("finish"); } }