SubscriberMethodFinder 大体就是去注册后对应的方法
其中,属性
private static final int BRIDGE = 0x40;
有对应的说明:
In newer class files, compilers may add methods. Those are called bridge or synthetic methods.
EventBus must ignore both. There modifiers are not public but defined in the Java class file format:
http://docs.oracle.com/javase/specs/jvms/se7/html/jvms-4.html#jvms-4.6-200-A.1
自己也没有研究过jvm,简单贴一下图
下面对应的变量修饰符
private static final int MODIFIERS_IGNORE = Modifier.ABSTRACT | Modifier.STATIC | BRIDGE | SYNTHETIC;
也就是, 方法上的注解,会忽略这几种修饰符的方法
先重点看一下这2个容器
一个是 : 本类存储的容器类,用于 查找 和 存储 另一个是 :传入的引用
Eventbus3
这里,我们可以发现, 除了 构造 和 findSubscriberMethods方法 是 public对外的 其他,都是 private 的 也就是,我们主要认识 findSubscriberMethods方法 即可
和EventBus 2.4 对比
EventBus 2.4
我们大体可以猜测,其他多余出来的方法,都是用于判断反射的
先一起大体过一下
List<SubscriberMethod> findSubscriberMethods(Class<?> subscriberClass) {
List<SubscriberMethod> subscriberMethods = METHOD_CACHE.get(subscriberClass);
if (subscriberMethods != null) {
return subscriberMethods;
}
if (ignoreGeneratedIndex) {
subscriberMethods = findUsingReflection(subscriberClass);
} else {
subscriberMethods = findUsingInfo(subscriberClass);
}
if (subscriberMethods.isEmpty()) {
throw new EventBusException("Subscriber " + subscriberClass
+ " and its super classes have no public methods with the @Subscribe annotation");
} else {
METHOD_CACHE.put(subscriberClass, subscriberMethods);
return subscriberMethods;
}
}
这里,大体就是
上面提到的 如果Map缓存中 没有值,并且 ignoreGeneratedIndex为false的时候 会调用这个方法 具体看下源码
private List<SubscriberMethod> findUsingInfo(Class<?> subscriberClass) {
FindState findState = prepareFindState();
findState.initForSubscriber(subscriberClass);
while (findState.clazz != null) {
findState.subscriberInfo = getSubscriberInfo(findState);
if (findState.subscriberInfo != null) {
SubscriberMethod[] array = findState.subscriberInfo.getSubscriberMethods();
for (SubscriberMethod subscriberMethod : array) {
if (findState.checkAdd(subscriberMethod.method, subscriberMethod.eventType)) {
findState.subscriberMethods.add(subscriberMethod);
}
}
} else {
findUsingReflectionInSingleClass(findState);
}
findState.moveToSuperclass();
}
return getMethodsAndRelease(findState);
}
这里通过 prepareFindState(), 获取 FindState 对象 (具体方法,见下面的方法说明)
这里因为上面的方法会获取这个对象 所以,我们先来看一下这个对象
static class FindState {
final List<SubscriberMethod> subscriberMethods = new ArrayList<>();
final Map<Class, Object> anyMethodByEventType = new HashMap<>();
final Map<String, Class> subscriberClassByMethodKey = new HashMap<>();
final StringBuilder methodKeyBuilder = new StringBuilder(128);
Class<?> subscriberClass;
Class<?> clazz;
boolean skipSuperClasses;
SubscriberInfo subscriberInfo;
void initForSubscriber(Class<?> subscriberClass) {
this.subscriberClass = clazz = subscriberClass;
skipSuperClasses = false;
subscriberInfo = null;
}
void recycle() {
subscriberMethods.clear();
anyMethodByEventType.clear();
subscriberClassByMethodKey.clear();
methodKeyBuilder.setLength(0);
subscriberClass = null;
clazz = null;
skipSuperClasses = false;
subscriberInfo = null;
}
boolean checkAdd(Method method, Class<?> eventType) {
// 2 level check: 1st level with event type only (fast), 2nd level with complete signature when required.
// Usually a subscriber doesn't have methods listening to the same event type.
Object existing = anyMethodByEventType.put(eventType, method);
if (existing == null) {
return true;
} else {
if (existing instanceof Method) {
if (!checkAddWithMethodSignature((Method) existing, eventType)) {
// Paranoia check
throw new IllegalStateException();
}
// Put any non-Method object to "consume" the existing Method
anyMethodByEventType.put(eventType, this);
}
return checkAddWithMethodSignature(method, eventType);
}
}
private boolean checkAddWithMethodSignature(Method method, Class<?> eventType) {
methodKeyBuilder.setLength(0);
methodKeyBuilder.append(method.getName());
methodKeyBuilder.append('>').append(eventType.getName());
String methodKey = methodKeyBuilder.toString();
Class<?> methodClass = method.getDeclaringClass();
Class<?> methodClassOld = subscriberClassByMethodKey.put(methodKey, methodClass);
if (methodClassOld == null || methodClassOld.isAssignableFrom(methodClass)) {
// Only add if not already found in a sub class
return true;
} else {
// Revert the put, old class is further down the class hierarchy
subscriberClassByMethodKey.put(methodKey, methodClassOld);
return false;
}
}
void moveToSuperclass() {
if (skipSuperClasses) {
clazz = null;
} else {
clazz = clazz.getSuperclass();
String clazzName = clazz.getName();
/** Skip system classes, this just degrades performance. */
if (clazzName.startsWith("java.") || clazzName.startsWith("javax.") || clazzName.startsWith("android.")) {
clazz = null;
}
}
}
}
这个代码比较长,我们大体看一下即可
大体就是
这里是前面 findUsingInfo方法 中用到的 也就是用来获取FindState对象的方法
private FindState prepareFindState() {
synchronized (FIND_STATE_POOL) {
for (int i = 0; i < POOL_SIZE; i++) {
FindState state = FIND_STATE_POOL[i];
if (state != null) {
FIND_STATE_POOL[i] = null;
return state;
}
}
}
return new FindState();
}
这里,知道这里有一个 FIND_STATE_POOL 对象池 对象个数 POOL_SIZE 为 4 具体对象为 FindState 是一个 静态内部类 for循环取值:
先看一下源码
private List<SubscriberMethod> getMethodsAndRelease(FindState findState) {
List<SubscriberMethod> subscriberMethods = new ArrayList<>(findState.subscriberMethods);
findState.recycle();
synchronized (FIND_STATE_POOL) {
for (int i = 0; i < POOL_SIZE; i++) {
if (FIND_STATE_POOL[i] == null) {
FIND_STATE_POOL[i] = findState;
break;
}
}
}
return subscriberMethods;
}
这里大体就是获取 FindState中的List<SubscriberMethod>类型的对象subscriberMethods 将对应的FindState对象放入对象池中 最后返回List<SubscriberMethod>的值
也先看一下源码
private SubscriberInfo getSubscriberInfo(FindState findState) {
if (findState.subscriberInfo != null && findState.subscriberInfo.getSuperSubscriberInfo() != null) {
SubscriberInfo superclassInfo = findState.subscriberInfo.getSuperSubscriberInfo();
if (findState.clazz == superclassInfo.getSubscriberClass()) {
return superclassInfo;
}
}
if (subscriberInfoIndexes != null) {
for (SubscriberInfoIndex index : subscriberInfoIndexes) {
SubscriberInfo info = index.getSubscriberInfo(findState.clazz);
if (info != null) {
return info;
}
}
}
return null;
}
也就是如果传入的findState对象不空,并且有SubscriberInfo的值 (这块自己感觉没有赋值的地方,应该为null,具体先不纠结) 或者对应的值,并且SubscriberInfo不为空,Class相同的时候, 返回对应的SubscriberInfo对象
如果上面不符合,会取从构造传进来的subscriberInfoIndexes对象中 for循环,获取第一个 SubscriberInfo 对象
这里就不贴代码了 大体为:
上面用到的 大体为:
对外,就2个方法
对应的方法,会存入 Map<Class<?>, List<SubscriberMethod>> METHOD_CACHE = new ConcurrentHashMap<>() 容器中
(其实,自己不太理解,这里为什么用一个容器存储,为什么要这样写结构 等等,只是简单的叙述了下流程,等有时间,再考虑一下)