创建一个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());