• EventBus 源码学习


    打开一看,原来相关代码并不多,下面看下细节

    主要方法也就是注册,取消注册和发送事件,可以看到两个主要的变量就是subscribers和dispatcher

      public void register(Object object) {
        subscribers.register(object);
      }

    首先看下注册类中做了什么,在下面的注册类中,可以看到首先调用了这个方法,对传入的listener类型,利用反射拿到信息

      /**
       * Returns all subscribers for the given listener grouped by the type of event they subscribe to.
       */
      private Multimap<Class<?>, Subscriber> findAllSubscribers(Object listener) {
        Multimap<Class<?>, Subscriber> methodsInListener = HashMultimap.create();
        Class<?> clazz = listener.getClass();
        for (Method method : getAnnotatedMethods(clazz)) {
          Class<?>[] parameterTypes = method.getParameterTypes();
          Class<?> eventType = parameterTypes[0];
          methodsInListener.put(eventType, Subscriber.create(bus, listener, method));
        }
        return methodsInListener;
      }

    debug下就清楚了

      /** Registers all subscriber methods on the given listener object. */
      void register(Object listener) {
        Multimap<Class<?>, Subscriber> listenerMethods = findAllSubscribers(listener);
    
        for (Entry<Class<?>, Collection<Subscriber>> entry : listenerMethods.asMap().entrySet()) {
          Class<?> eventType = entry.getKey();
          Collection<Subscriber> eventMethodsInListener = entry.getValue();
    
          CopyOnWriteArraySet<Subscriber> eventSubscribers = subscribers.get(eventType);
    
          if (eventSubscribers == null) {
            CopyOnWriteArraySet<Subscriber> newSet = new CopyOnWriteArraySet<>();
            eventSubscribers =
                MoreObjects.firstNonNull(subscribers.putIfAbsent(eventType, newSet), newSet);
          }
    
          eventSubscribers.addAll(eventMethodsInListener);
        }
      }

     

    注册后这里的订阅者会保存如下信息。

    其次是分发

      public void post(Object event) {
        Iterator<Subscriber> eventSubscribers = subscribers.getSubscribers(event);
        if (eventSubscribers.hasNext()) {
          dispatcher.dispatch(event, eventSubscribers);
        } else if (!(event instanceof DeadEvent)) {
          // the event had no subscribers and was not itself a DeadEvent
          post(new DeadEvent(this, event));
        }
      }

    可见是先拿注册信息,再分发

        @Override
        void dispatch(Object event, Iterator<Subscriber> subscribers) {
          checkNotNull(event);
          checkNotNull(subscribers);
          Queue<Event> queueForThread = queue.get();
          queueForThread.offer(new Event(event, subscribers));
    
          if (!dispatching.get()) {
            dispatching.set(true);
            try {
              Event nextEvent;
              while ((nextEvent = queueForThread.poll()) != null) {
                while (nextEvent.subscribers.hasNext()) {
                  nextEvent.subscribers.next().dispatchEvent(nextEvent.event);
                }
              }
            } finally {
              dispatching.remove();
              queue.remove();
            }
          }
        }

     这里的dispatch通过反射执行

      /** Dispatches {@code event} to this subscriber using the proper executor. */
      final void dispatchEvent(final Object event) {
        executor.execute(
            new Runnable() {
              @Override
              public void run() {
                try {
                  invokeSubscriberMethod(event);
                } catch (InvocationTargetException e) {
                  bus.handleSubscriberException(e.getCause(), context(event));
                }
              }
            });
      }

    再下级

      /**
       * Invokes the subscriber method. This method can be overridden to make the invocation
       * synchronized.
       */
      @VisibleForTesting
      void invokeSubscriberMethod(Object event) throws InvocationTargetException {
        try {
          method.invoke(target, checkNotNull(event));
        } catch (IllegalArgumentException e) {
          throw new Error("Method rejected target/argument: " + event, e);
        } catch (IllegalAccessException e) {
          throw new Error("Method became inaccessible: " + event, e);
        } catch (InvocationTargetException e) {
          if (e.getCause() instanceof Error) {
            throw (Error) e.getCause();
          }
          throw e;
        }
      }

    至此结束调用,这种设计还蛮特别的,值得学习

  • 相关阅读:
    Redis存储对象(序列化和反序列化)
    JAVA中关于set()和get()方法的理解以及使用
    5W1H分析法
    Spring AOP的理解(通俗易懂)。
    Notepad++ 使用步骤,熟练掌握notepad++的使用技巧,无疑会大大提升专业技能。以及快捷键操作
    Int,String,Integer,double之间的类型的相互转换
    Ajax局部刷新和全局刷新的区别
    GET和POST都是什么时候用?
    ajax为什么需要json格式响应数据?
    final fially finalize区别
  • 原文地址:https://www.cnblogs.com/it-worker365/p/9945566.html
Copyright © 2020-2023  润新知