写这个建议框架为了便于观察者模式:
一 ,实现第一个类 import com.google.common.base.Preconditions; import java.lang.reflect.InvocationTargetException; import java.lang.reflect.Method; /** * 观察者综合类 */ public class ObserverAction { private Object target;//表示观察者的类 private Method method;//表示方法 public ObserverAction(Object target, Method method) { this.target = Preconditions.checkNotNull(target); this.method = method; this.method.setAccessible(true); } public void execute(Object event) { try { method.invoke(target, event); } catch (InvocationTargetException | IllegalAccessException e) { e.printStackTrace(); } } }
二 ,实现第二个类 import com.google.common.base.Preconditions; import java.lang.reflect.Method; import java.util.*; import java.util.concurrent.ConcurrentHashMap; import java.util.concurrent.ConcurrentMap; import java.util.concurrent.CopyOnWriteArraySet; /** * Event Bus 注册表类 */ public class ObserverRegistry { private static ConcurrentMap<Class<?>, CopyOnWriteArraySet<ObserverAction>> registry = new ConcurrentHashMap<>(); /** * 把它导入到另一个map里边 用的 CopyOnWriteArraySet 这样在复制完成之后在替换 * 避免冲突 * @param observer */ public void register(Object observer) { Map<Class<?>, Collection<ObserverAction>> observerActions = findAllObserverActions(observer); for (Map.Entry<Class<?>, Collection<ObserverAction>> entry : observerActions.entrySet()) { Class<?> eventType = entry.getKey(); Collection<ObserverAction> eventActions = entry.getValue(); CopyOnWriteArraySet<ObserverAction> registeredEventActions = registry.get(eventType); if(registeredEventActions==null){ registry.put(eventType, new CopyOnWriteArraySet<>()); registeredEventActions=registry.get(eventType); } registeredEventActions.addAll(eventActions); } } private Map<Class<?>, Collection<ObserverAction>> findAllObserverActions(Object observer) { Map<Class<?>, Collection<ObserverAction>> observerActions = new HashMap<>(); Class<?> clazz = observer.getClass(); for (Method method : getAnnotatedMethods(clazz)) { Class<?>[] parameterTypes = method.getParameterTypes(); Class<?> eventType = parameterTypes[0]; if (!observerActions.containsKey(eventType)) {//不存在这种类型,也即是说一个类里边要存在不同值的参数类型才可以 observerActions.put(eventType, new ArrayList<>()); } observerActions.get(eventType).add(new ObserverAction(observer, method)); } return observerActions; } /** * 筛选出方法中带有@Subscribe标签的 * * @param clazz * @return */ private List<Method> getAnnotatedMethods(Class<?> clazz) { List<Method> annotatedMethods = new ArrayList<>(); for (Method method : clazz.getDeclaredMethods()) {//获取所有public方法 if (method.isAnnotationPresent(Subscribe.class)) {//如果该方法上有@Subscribe标签 //检查下这个方法中是否有参数 Class<?>[] parameterTypes = method.getParameterTypes(); Preconditions.checkArgument(parameterTypes.length == 1, "Method %s has @Subscribe annotation but has %s parameters." + "Subscriber methods must have exactly 1 parameter.", method, parameterTypes.length); annotatedMethods.add(method); } } return annotatedMethods; } }
三 ,实现一个标签 import com.google.common.annotations.Beta; import java.lang.annotation.ElementType; import java.lang.annotation.Retention; import java.lang.annotation.RetentionPolicy; import java.lang.annotation.Target; @Retention(RetentionPolicy.RUNTIME) @Target(ElementType.METHOD) @Beta public @interface Subscribe { }
四 ,实现测试类 package com.jxd.bus; public class Test { @Subscribe public void aaa(String a){ System.out.println("hell world Test"+a); } }
五 ,测试结果
public static void main(String[] args) {
Test t =new Test(); new ObserverRegistry().register(t);
System.out.println(registry.size());
Iterator<ObserverAction> a=registry.get(String.class).iterator();
a.next().execute(" Event BUS ");
}
打印结果
hell world Test Event BUS