Guava EventBus 原理

2019独角兽企业重金招聘Python工程师标准>>> hot3.png

创建一个Map  key可以重复的:


//参数就是一个普通的Listener 
private Multimap, Subscriber> findAllSubscribers(Object listener) {
    //创建一个key 可以重复的Map key : class 信息 Subscriber Value 是订阅者
    Multimap, Subscriber> methodsInListener = HashMultimap.create();
    Class clazz = listener.getClass();
    //getAnnotatedMethods 构建缓存 从初始化信息里面拿到所有加上注解的方法集合 
    for (Method method : getAnnotatedMethods(clazz)) {
    //获取参数类型
      Class[] parameterTypes = method.getParameterTypes();
      //获取EventType的类型 时间类型
      Class eventType = parameterTypes[0];
      //确定了 Event class 和 时间响应者的关系
      //也就是解决了为啥EventBus 注册了了的Listener 的参数来响应指定的事件
      methodsInListener.put(eventType, Subscriber.create(bus, listener, method));
    }
    return methodsInListener;
}


private static final LoadingCache, ImmutableList> subscriberMethodsCache =
      CacheBuilder.newBuilder()
          .weakKeys()
          .build(new CacheLoader, ImmutableList>() {
            @Override
            public ImmutableList load(Class concreteClass) throws Exception {
              return getAnnotatedMethodsNotCached(concreteClass);
            }
});

//最终返回的是一个所有加了指定注解的方法集合  方法名称+参数 进行去重  最终返回所有的方法对象 有了方法就可以进行反射
//为啥不扫描所有的方法直接注册 还需要判重 是为了过滤掉继承的方法吗 留意一点 
//去重的条件究竟是为了什么:
//父子类的继承只需要注册一个子类就可以了 (需要验证是否正确)
//缓存初始化 获取父类的接口名称 拿到当前类自己+当前类的父类货接口 的所有类,放在一个Set中
Set> supertypes = TypeToken.of(clazz).getTypes().rawTypes();
    Map identifiers = Maps.newHashMap();
    for (Class supertype : supertypes) {
      for (Method method : supertype.getDeclaredMethods()) {
        // 过滤掉Synthetic (合成)方法是由编译器产生的、源代码中没有的方法
        if (method.isAnnotationPresent(Subscribe.class) && !method.isSynthetic()) {
          // TODO(cgdecker): Should check for a generic parameter type and error out
          //方法的参数必须判断
          Class[] parameterTypes = method.getParameterTypes();
          checkArgument(parameterTypes.length == 1,
              "Method %s has @Subscribe annotation but has %s parameters."
                  + "Subscriber methods must have exactly 1 parameter.",
              method, parameterTypes.length);
          /**
             name  parameterTypes
          */

          //构建一个方法的标识符对象 由方法名称和方法对象参数组成
          MethodIdentifier ident = new MethodIdentifier(method);
          if (!identifiers.containsKey(ident)) {
            identifiers.put(ident, method);
          }
        }
      }
    }
return ImmutableList.copyOf(identifiers.values());

转载于:https://my.oschina.net/payzheng/blog/1560054

你可能感兴趣的:(Guava EventBus 原理)