Guava EventBus 原理

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


//参数就是一个普通的Listener 
private Multimap<Class<?>, Subscriber> findAllSubscribers(Object listener) {
    //创建一个key 可以重复的Map key : class 信息 Subscriber Value 是订阅者
    Multimap<Class<?>, 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<Class<?>, ImmutableList<Method>> subscriberMethodsCache =
      CacheBuilder.newBuilder()
          .weakKeys()
          .build(new CacheLoader<Class<?>, ImmutableList<Method>>() {
            @Override
            public ImmutableList<Method> load(Class<?> concreteClass) throws Exception {
              return getAnnotatedMethodsNotCached(concreteClass);
            }
});

//最终返回的是一个所有加了指定注解的方法集合  方法名称+参数 进行去重  最终返回所有的方法对象 有了方法就可以进行反射
//为啥不扫描所有的方法直接注册 还需要判重 是为了过滤掉继承的方法吗 留意一点 
//去重的条件究竟是为了什么:
//父子类的继承只需要注册一个子类就可以了 (需要验证是否正确)
//缓存初始化 获取父类的接口名称 拿到当前类自己+当前类的父类货接口 的所有类,放在一个Set中
Set<? extends Class<?>> supertypes = TypeToken.of(clazz).getTypes().rawTypes();
    Map<MethodIdentifier, Method> 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

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值