美文网首页开源库
Otto源码分析

Otto源码分析

作者: 不二先生的世界 | 来源:发表于2016-06-20 03:05 被阅读306次

    Otto是Square公司推出的事件总线库,目的是当你应用里的不同部分需要进行通讯时进行解耦。

    使用方法

    Otto的使用方法非常简单,有很多中文资料都有对其的入门介绍,如果英文不错,可以直接看官方文档

    源码分析

    UML类图

    UML类图.png

    源码分析

    Otto的原理就是使用反射完成方法的调用。
    Bus构造函数

      //用来区分事件总线,默认值是“default”
      private final String identifier;
      //用于注册,取消,发送事件的线程执行者,默认值是ThreadEnforcer.MAIN,即主线程
      private final ThreadEnforcer enforcer;
      //用户查找在注册和取消中的处理方法,默认值是HandlerFinder.ANNOTATED
      private final HandlerFinder handlerFinder;
    
      public Bus() {
        this(DEFAULT_IDENTIFIER);
      }
      public Bus(String identifier) {
        this(ThreadEnforcer.MAIN, identifier);
      }
      public Bus(ThreadEnforcer enforcer) {
        this(enforcer, DEFAULT_IDENTIFIER);
      }
      public Bus(ThreadEnforcer enforcer, String identifier) {
        this(enforcer, identifier, HandlerFinder.ANNOTATED);
      }
      Bus(ThreadEnforcer enforcer, String identifier, HandlerFinder handlerFinder) {
        this.enforcer =  enforcer;
        this.identifier = identifier;
        this.handlerFinder = handlerFinder;
      }
    

    register

    public void register(Object object) {
        if (object == null) {
          throw new NullPointerException("Object to register must not be null.");
        }
        //判断是否在配置的线程内部进行事件发送,默认是主线程
        enforcer.enforce(this);
    
        //找到所有的Producers
        Map<Class<?>, EventProducer> foundProducers = handlerFinder.findAllProducers(object);
        for (Class<?> type : foundProducers.keySet()) {
    
          final EventProducer producer = foundProducers.get(type);
          EventProducer previousProducer = producersByType.putIfAbsent(type, producer);
          //checking if the previous producer existed
          if (previousProducer != null) {
            throw new IllegalArgumentException("Producer method for type " + type
              + " found on type " + producer.target.getClass()
              + ", but already registered by type " + previousProducer.target.getClass() + ".");
          }
    
          Set<EventHandler> handlers = handlersByType.get(type);
          if (handlers != null && !handlers.isEmpty()) {
            for (EventHandler handler : handlers) {
              //处理Producer
              dispatchProducerResultToHandler(handler, producer);
            }
          }
        }
    
        //找到所有的Subscribers
        Map<Class<?>, Set<EventHandler>> foundHandlersMap = handlerFinder.findAllSubscribers(object);
        for (Class<?> type : foundHandlersMap.keySet()) {
          Set<EventHandler> handlers = handlersByType.get(type);
          if (handlers == null) {
            //如果不存在,则并发存储
            Set<EventHandler> handlersCreation = new CopyOnWriteArraySet<EventHandler>();
            handlers = handlersByType.putIfAbsent(type, handlersCreation);
            if (handlers == null) {
                handlers = handlersCreation;
            }
          }
          final Set<EventHandler> foundHandlers = foundHandlersMap.get(type);
          if (!handlers.addAll(foundHandlers)) {
            throw new IllegalArgumentException("Object already registered.");
          }
        }
    
        for (Map.Entry<Class<?>, Set<EventHandler>> entry : foundHandlersMap.entrySet()) {
          Class<?> type = entry.getKey();
          EventProducer producer = producersByType.get(type);
          if (producer != null && producer.isValid()) {
            Set<EventHandler> foundHandlers = entry.getValue();
            for (EventHandler foundHandler : foundHandlers) {
              //如果producer无效
              if (!producer.isValid()) {
                break;
              }
              if (foundHandler.isValid()) {
                //处理Producer
                dispatchProducerResultToHandler(foundHandler, producer);
              }
            }
          }
        }
      }
    

    findAllSubscribers

    static Map<Class<?>, Set<EventHandler>> findAllSubscribers(Object listener) {
        Class<?> listenerClass = listener.getClass();
        Map<Class<?>, Set<EventHandler>> handlersInMethod = new HashMap<Class<?>, Set<EventHandler>>();
        //从Subscribers内存缓存中读取methods
        Map<Class<?>, Set<Method>> methods = SUBSCRIBERS_CACHE.get(listenerClass);
        if (null == methods) {
          methods = new HashMap<Class<?>, Set<Method>>();
          //使用注释加载Subscriber Methods
          loadAnnotatedSubscriberMethods(listenerClass, methods);
        }
        if (!methods.isEmpty()) {
          for (Map.Entry<Class<?>, Set<Method>> e : methods.entrySet()) {
            Set<EventHandler> handlers = new HashSet<EventHandler>();
            for (Method m : e.getValue()) {
              //新增所有的EventHandler
              handlers.add(new EventHandler(listener, m));
            }
            //以Class作为Key保存EventHandler集合
            handlersInMethod.put(e.getKey(), handlers);
          }
        }
    
        return handlersInMethod;
      }
    }
    
    private static void loadAnnotatedSubscriberMethods(Class<?> listenerClass,
          Map<Class<?>, Set<Method>> subscriberMethods) {
        Map<Class<?>, Method> producerMethods = new HashMap<Class<?>, Method>();
        loadAnnotatedMethods(listenerClass, producerMethods, subscriberMethods);
      }
    
      private static void loadAnnotatedMethods(Class<?> listenerClass,
          Map<Class<?>, Method> producerMethods, Map<Class<?>, Set<Method>> subscriberMethods) {
        for (Method method : listenerClass.getDeclaredMethods()) {
          //判断该method是否是桥接模式,因为在编译过程中,有时候会动态产生桥接方法
          if (method.isBridge()) {
            continue;
          }
          //如果是Subscribe注释
          if (method.isAnnotationPresent(Subscribe.class)) {
            Class<?>[] parameterTypes = method.getParameterTypes();
            //判断参数数量是否是1
            if (parameterTypes.length != 1) {
              throw new IllegalArgumentException("Method " + method + " has @Subscribe annotation but requires "
                  + parameterTypes.length + " arguments.  Methods must require a single argument.");
            }
    
            Class<?> eventType = parameterTypes[0];
            //判断第一个参数是不是接口
            if (eventType.isInterface()) {
              throw new IllegalArgumentException("Method " + method + " has @Subscribe annotation on " + eventType
                  + " which is an interface.  Subscription must be on a concrete class type.");
            }
    
            //判断方法访问权限是否是Public
            if ((method.getModifiers() & Modifier.PUBLIC) == 0) {
              throw new IllegalArgumentException("Method " + method + " has @Subscribe annotation on " + eventType
                  + " but is not 'public'.");
            }
    
            Set<Method> methods = subscriberMethods.get(eventType);
            if (methods == null) {
              methods = new HashSet<Method>();
              subscriberMethods.put(eventType, methods);
            }
            methods.add(method);
          } 
          //如果是Produce注释
          else if (method.isAnnotationPresent(Produce.class)) {
            Class<?>[] parameterTypes = method.getParameterTypes();
            //判断参数数量是否是0
            if (parameterTypes.length != 0) {
              throw new IllegalArgumentException("Method " + method + "has @Produce annotation but requires "
                  + parameterTypes.length + " arguments.  Methods must require zero arguments.");
            }
            //判断返回值是否是Void
            if (method.getReturnType() == Void.class) {
              throw new IllegalArgumentException("Method " + method
                  + " has a return type of void.  Must declare a non-void type.");
            }
    
            Class<?> eventType = method.getReturnType();
            //判断返回类型是否是接口
            if (eventType.isInterface()) {
              throw new IllegalArgumentException("Method " + method + " has @Produce annotation on " + eventType
                  + " which is an interface.  Producers must return a concrete class type.");
            }
            //判断返回值是否是Void
            if (eventType.equals(Void.TYPE)) {
              throw new IllegalArgumentException("Method " + method + " has @Produce annotation but has no return type.");
            }
    
            //判断方法访问权限是否是Public
            if ((method.getModifiers() & Modifier.PUBLIC) == 0) {
              throw new IllegalArgumentException("Method " + method + " has @Produce annotation on " + eventType
                  + " but is not 'public'.");
            }
            //判断producerMethods里的eventType是否存在
            if (producerMethods.containsKey(eventType)) {
              throw new IllegalArgumentException("Producer for type " + eventType + " has already been registered.");
            }
            producerMethods.put(eventType, method);
          }
        }
        
        //对producer和subscriber进行缓存
        PRODUCERS_CACHE.put(listenerClass, producerMethods);
        SUBSCRIBERS_CACHE.put(listenerClass, subscriberMethods);
      }
    

    findAllProducers和findAllSubscriber类似

    unregister

    public void unregister(Object object) {
        if (object == null) {
          throw new NullPointerException("Object to unregister must not be null.");
        }
        //判断是否在配置的线程内部进行事件发送,默认是主线程
        enforcer.enforce(this);
    
        Map<Class<?>, EventProducer> producersInListener = handlerFinder.findAllProducers(object);
        for (Map.Entry<Class<?>, EventProducer> entry : producersInListener.entrySet()) {
          final Class<?> key = entry.getKey();
          EventProducer producer = getProducerForEventType(key);
          EventProducer value = entry.getValue();
    
          if (value == null || !value.equals(producer)) {
            throw new IllegalArgumentException(
                "Missing event producer for an annotated method. Is " + object.getClass()
                    + " registered?");
          }
          //移除producersByType里内容,并且将其置成无效
          producersByType.remove(key).invalidate();
        }
    
        Map<Class<?>, Set<EventHandler>> handlersInListener = handlerFinder.findAllSubscribers(object);
        for (Map.Entry<Class<?>, Set<EventHandler>> entry : handlersInListener.entrySet()) {
          Set<EventHandler> currentHandlers = getHandlersForEventType(entry.getKey());
          Collection<EventHandler> eventMethodsInListener = entry.getValue();
    
          if (currentHandlers == null || !currentHandlers.containsAll(eventMethodsInListener)) {
            throw new IllegalArgumentException(
                "Missing event handler for an annotated method. Is " + object.getClass()
                    + " registered?");
          }
    
          for (EventHandler handler : currentHandlers) {
            if (eventMethodsInListener.contains(handler)) {
              //置成无效
              handler.invalidate();
            }
          }
          //移除currentHandlers里内容
          currentHandlers.removeAll(eventMethodsInListener);
        }
      }
    

    post

    public void post(Object event) {
        if (event == null) {
          throw new NullPointerException("Event to post must not be null.");
        }
        enforcer.enforce(this);
        //获取class集合,包括其父类
        Set<Class<?>> dispatchTypes = flattenHierarchy(event.getClass());
    
        boolean dispatched = false;
        for (Class<?> eventType : dispatchTypes) {
          //根据class获取EventHandler集合
          Set<EventHandler> wrappers = getHandlersForEventType(eventType);
    
          if (wrappers != null && !wrappers.isEmpty()) {
            dispatched = true;
            for (EventHandler wrapper : wrappers) {
              //将事件插入队列
              enqueueEvent(event, wrapper);
            }
          }
        }
    
        if (!dispatched && !(event instanceof DeadEvent)) {
          post(new DeadEvent(this, event));
        }
        //派遣事件队列
        dispatchQueuedEvents();
      }
    
      protected void dispatchQueuedEvents() {
        //如果处于派遣中,则得到本次派遣结束后再派遣
        if (isDispatching.get()) {
          return;
        }
    
        isDispatching.set(true);
        try {
          while (true) {
            //循环获取需要派遣的事件
            EventWithHandler eventWithHandler = eventsToDispatch.get().poll();
            //如果没有,则退出
            if (eventWithHandler == null) {
              break;
            }
            //如果事件有效,则进行派遣
            if (eventWithHandler.handler.isValid()) {
              dispatch(eventWithHandler.event, eventWithHandler.handler);
            }
          }
        } finally {
          isDispatching.set(false);
        }
      }
    
      protected void dispatch(Object event, EventHandler wrapper) {
        try {
          wrapper.handleEvent(event);
        } catch (InvocationTargetException e) {
          throwRuntimeException(
              "Could not dispatch event: " + event.getClass() + " to handler " + wrapper, e);
        }
      }
    
      public void handleEvent(Object event) throws InvocationTargetException {
        if (!valid) {
          throw new IllegalStateException(toString() + " has been invalidated and can no longer handle events.");
        }
        try {
          //利用反射执行目标函数
          method.invoke(target, event);
        } catch (IllegalAccessException e) {
          throw new AssertionError(e);
        } catch (InvocationTargetException e) {
          if (e.getCause() instanceof Error) {
            throw (Error) e.getCause();
          }
          throw e;
        }
      }
    

    参考资料

    Otto Github
    Otto官网

    可以随意转发,也欢迎关注我的简书,我会坚持给大家带来分享。

    相关文章

      网友评论

        本文标题:Otto源码分析

        本文链接:https://www.haomeiwen.com/subject/jbbbdttx.html