Otto源码详解

Otto有何用处,什么时候使用otto,当你组件存在交互的时候,比如ActivityActivityActivityFragment,ActivityService,如果用最原始的方法交互的话,会显得代码沉余显得乱,而且不利于阅读,那么这时候就可以用Otto了,就像用eventBus一样。Otto定义了两个最重要的角色

1:事件生产者

2:事件订阅者

大体的意思就是客户端主动生产事件,看代码,对就是他

BusProvider.getInstance().post(produceLocationEvent());

produceLocationEvent()这句话被标记了一个@Produce注解,表示这个事件是被生产出来的

@Produce
	public LocationChangedEvent produceLocationEvent() {
		// Provide an initial value for location based on the last known
		// position.
		return new LocationChangedEvent(lastLatitude, lastLongitude);
	}

生产完事件之后呢?当然是把事件传递给订阅者了,那么也就是生产者生产事件后,将事件放入队列中,然后检查队列的事件有没有订阅者订阅,如果订阅的话就将事件传给订阅者。下面是订阅者的注解 @Subscribe

@Subscribe public void onLocationChanged(LocationChangedEvent event) {
    // Stop existing download, if it exists.
    if (downloadTask != null) {
      downloadTask.cancel(true);
    }

    // Trigger a background download of an image for the new location.
    downloadTask = new DownloadTask();
    downloadTask.execute(String.format(URL, event.lat, event.lon));
  }
官方例子提供了 ActivityFrament的交互,那么下面顺着例子一步一步的走,首先不管订阅还是生产都需要将当前的对象注册进组件,那么从注册开始

BusProvider.getInstance().register(this);
当前对象带有生产者和订阅者的注解,那么想让注解生效必须实现注册,那么接着看注册给我们实现了什么

public void register(Object object) {
    if (object == null) {
      throw new NullPointerException("Object to register must not be null.");
    }
    //检查是否是主线程,不是抛异常
    enforcer.enforce(this);
    //此处的handlerFinder传给AnnotatedHandlerFinder去查询
    Map<Class<?>, EventProducer> foundProducers = handlerFinder.findAllProducers(object);
    for (Class<?> type : foundProducers.keySet()) {
      //此处type是生产者返回值的类型
      final EventProducer producer = foundProducers.get(type);
      //如果集合中没有存储返回null,防止重复存储
      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) {
          dispatchProducerResultToHandler(handler, producer);
        }
      }
    }
   /**
   * 查询所有的订阅者
    */
    Map<Class<?>, Set<EventHandler>> foundHandlersMap = handlerFinder.findAllSubscribers(object);
    for (Class<?> type : foundHandlersMap.keySet()) {
      Set<EventHandler> handlers = handlersByType.get(type);
      if (handlers == null) {
        //concurrent put if absent
        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) {
          if (!producer.isValid()) {
            break;
          }
          if (foundHandler.isValid()) {
            dispatchProducerResultToHandler(foundHandler, producer);
          }
        }
      }
    }
  }
这个方法的代码比较多,那么一点一点的分析,首先看一下 enforcer是什么?

public interface ThreadEnforcer {

  /**
   * Enforce a valid thread for the given {@code bus}. Implementations may throw any runtime exception.
   *
   * @param bus Event bus instance on which an action is being performed.
   */
  void enforce(Bus bus);


  /** A {@link ThreadEnforcer} that does no verification. */
  ThreadEnforcer ANY = new ThreadEnforcer() {
    @Override public void enforce(Bus bus) {
      // Allow any thread.
    }
  };

奥,他是一个接口,那么Bus里面的 ThreadEnforcer是哪一个实现类呢?

 public Bus(String identifier) {
    this(ThreadEnforcer.MAIN, identifier);
  }

bus的不带参构造函数,默认调用带参构造函数,也就是给了一个默认实现类

/**
  * 默认
  */
  ThreadEnforcer MAIN = new ThreadEnforcer() {
    @Override public void enforce(Bus bus) {
    	/**
    	 * 如果不是主线程抛异常
    	 */
      if (Looper.myLooper() != Looper.getMainLooper()) {
        throw new IllegalStateException("Event bus " + bus + " accessed from non-main thread " + Looper.myLooper());
      }
    }
  };

这个默认实现接口的类检查注册是不是在主线程,不在主线程则抛异常。当然我们可以扩展到子线程里面执行。

  Map<Class<?>, EventProducer> foundProducers = handlerFinder.findAllProducers(object);
接下来就是这句根据传过来的对象查询事件生产者,进去看看什么鬼

/**
 * 默认的实现类
 */
  HandlerFinder ANNOTATED = new HandlerFinder() {
    @Override
    public Map<Class<?>, EventProducer> findAllProducers(Object listener) {
      return AnnotatedHandlerFinder.findAllProducers(listener);
    }

    @Override
    public Map<Class<?>, Set<EventHandler>> findAllSubscribers(Object listener) {
      return AnnotatedHandlerFinder.findAllSubscribers(listener);
    }
  };

查找handler的类也是采用的默认实现类,而真正进行查询的是 AnnotatedHandlerFinder的静态方法,从英文意思也大概可以猜测到,此方法采用了反射获得注解的信息,ok进入

 static Map<Class<?>, EventProducer> findAllProducers(Object listener) {
	  //反射得到class
    final Class<?> listenerClass = listener.getClass();
    //新创建一个集合
    Map<Class<?>, EventProducer> handlersInMethod = new HashMap<Class<?>, EventProducer>();
    /**
    * 从缓存中取集合如果有的话
     */
    Map<Class<?>, Method> methods = PRODUCERS_CACHE.get(listenerClass);
    if (null == methods) {
      methods = new HashMap<Class<?>, Method>();
      loadAnnotatedProducerMethods(listenerClass, methods);
    }
    /*
     * 将当前事件注册进去
     */
    if (!methods.isEmpty()) {
      for (Map.Entry<Class<?>, Method> e : methods.entrySet()) {
    	  //添加EventProducer生产者
        EventProducer producer = new EventProducer(listener, e.getValue());
        handlersInMethod.put(e.getKey(), producer);
      }
    }

    return handlersInMethod;
  }
首先通过对象获取class,然后查询生产者缓存池里面有没有,没有的话就,创建一个存放方法的子集合

 methods = new HashMap<Class<?>, Method>();
      loadAnnotatedProducerMethods(listenerClass, methods);
并开始解析注解,前面添加的注解终于要用到了,看到这可以了解到此框架把设计模式写的多么出神入化了,单一职责,一个类只负责自己的工作,面向对象:一个类可以有多个方法,所以 PRODUCERS_CACHE保存的是 HashMap<Class<?>, Method>(), 另外还用了享元模式,减少垃圾回收器的频繁操作,提高运行速度。而Bus类采用了外观模式
所有的操作以他为入口类,协调其他类工作。那么接着进入 loadAnnotatedProducerMethods

private static void loadAnnotatedProducerMethods(Class<?> listenerClass,
      Map<Class<?>, Method> producerMethods) {
    Map<Class<?>, Set<Method>> subscriberMethods = new HashMap<Class<?>, Set<Method>>();
    loadAnnotatedMethods(listenerClass, producerMethods, subscriberMethods);
  }

吆喝,这个过渡方法又创建了  Map<Class<?>, Set<Method>> subscriberMethods = new HashMap<Class<?>, Set<Method>>();专门存放订阅者方法的类,那么现在已经说明一个类即可以是事件生产者又可以是事件订阅者。

 /**
   * 添加所有注解的方法进集合
   */
  private static void loadAnnotatedMethods(Class<?> listenerClass,
      Map<Class<?>, Method> producerMethods, Map<Class<?>, Set<Method>> subscriberMethods) {
    for (Method method : listenerClass.getDeclaredMethods()) {
      // The compiler sometimes creates synthetic bridge methods as part of the
      // type erasure process. As of JDK8 these methods now include the same
      // annotations as the original declarations. They should be ignored for
      // subscribe/produce.
      if (method.isBridge()) {
        continue;
      }
      if (method.isAnnotationPresent(Subscribe.class)) {
    	  /**
    	   * 返回方法参数类型信息
    	   */
        Class<?>[] parameterTypes = method.getParameterTypes();
        /**
         * 订阅者只有一个参数
         */
        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>();
          //将methond
          subscriberMethods.put(eventType, methods);
        }
        //将方法储存到集合
        methods.add(method);
      } 
      //假如注解是生产者
      else if (method.isAnnotationPresent(Produce.class)) {
        Class<?>[] parameterTypes = method.getParameterTypes();
        if (parameterTypes.length != 0) {
          throw new IllegalArgumentException("Method " + method + "has @Produce annotation but requires "
              + parameterTypes.length + " arguments.  Methods must require zero arguments.");
        }
        /**
         * 生产者必须有返回值
         */
        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.");
        }
        /**
         * 必须有返回值,也就是有事件返回
         */
        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'.");
        }

        if (producerMethods.containsKey(eventType)) {
          throw new IllegalArgumentException("Producer for type " + eventType + " has already been registered.");
        }
        producerMethods.put(eventType, method);
      }
    }
   /**
   * 将生产者,订阅者加入集合
    */
    PRODUCERS_CACHE.put(listenerClass, producerMethods);
    SUBSCRIBERS_CACHE.put(listenerClass, subscriberMethods);
  }
通过class反射循环遍历每一个方法看它是否带有注解,假如带有生产者注解,那么解析判断是否符合规定,那么有哪些判断呢?先看一下生产者

Class<?>[] parameterTypes = method.getParameterTypes();
        //生产者不能有参数
        if (parameterTypes.length != 0) {
          throw new IllegalArgumentException("Method " + method + "has @Produce annotation but requires "
              + parameterTypes.length + " arguments.  Methods must require zero arguments.");
        }
        /**
         * 生产者必须有返回值,要不怎么把事件给订阅者
         */
        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.");
        }
        /**
         * 必须有返回值,也就是有事件返回
         */
        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'.");
        }

现在总结如下, otto给我们的事件生产者指定了这些规则:

1:事件生产者的方法必须有没有参数

2:事件生产者的方法必须有返回值且返回值必须是具体的对象

3:生产者方法修饰符必须是public


如果都满足条件的话 producerMethods.put(eventType, method),以返回值类型作为key值,以方法method作为value加入集合,其实返回值类型就是事件的类型,下面看一下事件订阅者

if (method.isAnnotationPresent(Subscribe.class)) {
    	  /**
    	   * 返回方法参数类型信息
    	   */
        Class<?>[] parameterTypes = method.getParameterTypes();
        /**
         * 订阅者只有一个参数
         */
        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>();
          //将methond
          subscriberMethods.put(eventType, methods);
        }
        //将方法储存到集合
        methods.add(method);
      } 


1:订阅者的方法只能有个参数,这个参数就是事件

2:方法修饰符同样是public

接下来同样将订阅者事件方法放入集合中,这里还有一个点要注意,事件必须是具体的对象,不能是object,因为有如下判断

  if (method.isBridge()) {
        continue;
      }

如果是 object则不注册。接下来执行

 /*
     * 将当前事件注册进去
     */
    if (!methods.isEmpty()) {
      for (Map.Entry<Class<?>, Method> e : methods.entrySet()) {
    	  //添加EventProducer生产者
        EventProducer producer = new EventProducer(listener, e.getValue());
        handlersInMethod.put(e.getKey(), producer);
      }
    }

查找到有方法注解的话,那么集合里会有数据,那么遍历集合,创建真正执行事件生产的类 EventProducer, 可见EventProducer存放了当前的注册的对象还有方法,当然反射调用方法的两个前提是1、有当前对象,2、有反射的method的对象,最终将他放入 handlersInMethod集合,key同样是事件的类型,最终返回 handlersInMethod集合

 for (Class<?> type : foundProducers.keySet()) {
      //此处type是生产者返回值的类型
      final EventProducer producer = foundProducers.get(type);
      //如果集合中没有存储返回null,防止重复存储
      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) {
          dispatchProducerResultToHandler(handler, producer);
        }
      }
    }

接下来遍历返回的集合,判断 producersByType集合是否有生产者的注册如果有的话,就抛异常,也就是说生产某个事件的类型只能有一款,然后判断 handlersByType中是否有该事件的订阅者,有的话通知订阅者,也就是假如先注册的同一个事件A的订阅者,此时还没有注册事件A的生产者,如果一旦注册了事件A的生产者,那么会回调订阅者的方法。
/**
   * 查询所有的订阅者
    */
    Map<Class<?>, Set<EventHandler>> foundHandlersMap = handlerFinder.findAllSubscribers(object);
    for (Class<?> type : foundHandlersMap.keySet()) {
      Set<EventHandler> handlers = handlersByType.get(type);
      if (handlers == null) {
        //concurrent put if absent
        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) {
          if (!producer.isValid()) {
            break;
          }
          if (foundHandler.isValid()) {
            dispatchProducerResultToHandler(foundHandler, producer);
          }
        }
      }
    }

接下来又查询所有的订阅者,流程和查询生产者类似,不再阐述!最终执行订阅事件的是 EventHandler类,被存入集合

接下来看生产事件后,怎么传给订阅者的

public void post(Object event) {
    if (event == null) {
      throw new NullPointerException("Event to post must not be null.");
    }
    /*
     * 是否在主线程中执行的
     * 
     */
    enforcer.enforce(this);
    //查找所有类的继承
    Set<Class<?>> dispatchTypes = flattenHierarchy(event.getClass());

    boolean dispatched = false;
    for (Class<?> eventType : dispatchTypes) {
    	/**
    	 * 查找此事件的订阅者
    	 */
      Set<EventHandler> wrappers = getHandlersForEventType(eventType);

      if (wrappers != null && !wrappers.isEmpty()) {
        dispatched = true;
        for (EventHandler wrapper : wrappers) {
        	//将事件加入队列
          enqueueEvent(event, wrapper);
        }
      }
    }
   /**
   * 如果没有找到的话并且事件不属于DeadEvent事件,执行DeadEvent事件
   */
    if (!dispatched && !(event instanceof DeadEvent)) {
    	//递归调用,最终啥也不执行
      post(new DeadEvent(this, event));
    }
//开始分发事件
    dispatchQueuedEvents();
  }
 先看 flattenHierarchy方法,此方法的作用是查找累的树形结构并把它放在集合中,look

 Set<Class<?>> flattenHierarchy(Class<?> concreteClass) {
    Set<Class<?>> classes = flattenHierarchyCache.get(concreteClass);
    if (classes == null) {
      Set<Class<?>> classesCreation = getClassesFor(concreteClass);
      classes = flattenHierarchyCache.putIfAbsent(concreteClass, classesCreation);
      if (classes == null) {
        classes = classesCreation;
      }
    }

    return classes;
  }

这里又用了一个集合储存事件class和他的所有超类,接着进入这个方法 getClassesFor(concreteClass);



/**
 * 将目标类的所有超类全部取出放在 Set<Class<?>>返回
 * @param concreteClass
 * @return
 */
  private Set<Class<?>> getClassesFor(Class<?> concreteClass) {
    List<Class<?>> parents = new LinkedList<Class<?>>();
    Set<Class<?>> classes = new HashSet<Class<?>>();

    parents.add(concreteClass);

    while (!parents.isEmpty()) {
      Class<?> clazz = parents.remove(0);
      classes.add(clazz);

      Class<?> parent = clazz.getSuperclass();
      if (parent != null) {
        parents.add(parent);
      }
    }
    return classes;
  }

很明显,循环读取父类class,如果有父类的话,将他放入 classes集合并返回,接下来就是遍历集合,取出所有的class进行匹配

Set<EventHandler> getHandlersForEventType(Class<?> type) {
    return handlersByType.get(type);
  }

检查订阅者集合中是否有订阅了当前事件的订阅者,有的话,将它放入队列

  */
  protected void enqueueEvent(Object event, EventHandler handler) {
    eventsToDispatch.get().offer(new EventWithHandler(event, handler));
  }

此处的 eventsToDispatch ConcurrentLinkedQueue链表队列

 protected void dispatchQueuedEvents() {
    // don't dispatch if we're already dispatching, that would allow reentrancy and out-of-order events. Instead, leave
    // the events to be dispatched after the in-progress dispatch is complete.
    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);
    }
  }

那么接下来就是遍历链表队列分发事件了,如果队列中有事件订阅者,并且是可以接收数据的,  dispatch(eventWithHandler.event, eventWithHandler.handler)开始执行订阅的事件方法

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

event是我们传过来的事件对象,那么接下来反射执行订阅者的方法


/**
	 * 处理事件
	 */
	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;
		}
	}

也就是这个方法

 @Subscribe 
  public void onLocationChanged(LocationChangedEvent event) {
    // Stop existing download, if it exists.
    if (downloadTask != null) {
      downloadTask.cancel(true);
    }
好了产生事件并把事件分给订阅者的流程就结束了,从中得到一个关键点,生产同一个事件的生产者只有一个,而订阅者可以有多个,也就是生产者和订阅者是1对多的关系。最后就是解绑订阅者和事件生产者了

/**
  * 取消注册
  * @param object
  */
  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.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.removeAll(eventMethodsInListener);
    }
  }


这个方法看起来很多,但是逻辑没有那么复杂,就是检查缓存集合中是否有当前对象绑定的事件生产者和消费者,有的话从 handlersByType集合或producersByType集合中清除,到此otto框架就分析完了,现在你可以尝试一下自己写一个eventbus实现自己组件之间的交互。










  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值