EventBus Register

EventBus Register

分析的EventBus是基于EventBus 3的,这个版本的EventBus会使用APT来提前生成一些信息,对注解在编译期进行解析,生成相应的Java,提高在运行时的调用效率。之前的版本中都是用的反射区解析相关的函数的,效率会低。

@Subscribe

EventBus的用法比较简单,主要就是用@Subscribe注解,那我们就先看@Subscribe会在编译期被怎么处理,生成的文件。至于如何生成的这个文件是APT相关的技术,这里不分析。下面看看生成的java文件

//订阅者信息索引
public interface SubscriberInfoIndex {
    SubscriberInfo getSubscriberInfo(Class<?> subscriberClass);//根据相应的订阅者类subscribeClass,得到相应的订阅者信息SubscribeInfo
}



/** This class is generated by EventBus, do not edit. */
//继承于订阅者信息索引SubScriberInfoIndex
public class MyEventBusIndex implements SubscriberInfoIndex {
     //订阅者索引的表格,key为订阅者类,value为订阅者信息SubscriberInfo
    private static final Map<Class<?>, SubscriberInfo> SUBSCRIBER_INDEX;

    static {
        SUBSCRIBER_INDEX = new HashMap<Class<?>, SubscriberInfo>();
        
        //把订阅者索引信息SubscriberInfo缓存在SUBSCRIBER_INDEX 静态HashMap里。在运行过程中会调用SubscriberInfo的getSubscriberMethods(),得到关于订阅者类SubscriberClass的所有的订阅方法的数组
        //@Subscribe注解的信息解析出来,封装成SubscriberMethodInfo对象
        
        putIndex(new SimpleSubscriberInfo(MainActivity.class, true, new SubscriberMethodInfo[] {
            new SubscriberMethodInfo("testEvent", MainActivity.class),
            new SubscriberMethodInfo("testEvent2", String.class, ThreadMode.MAIN, 1, false),
            new SubscriberMethodInfo("testEvent3", String.class, ThreadMode.MAIN),
            new SubscriberMethodInfo("onEvent", org.greenrobot.eventbus.SubscriberExceptionEvent.class),
        }));

        putIndex(new SimpleSubscriberInfo(SecondActivity.class, true, new SubscriberMethodInfo[] {
            new SubscriberMethodInfo("testEvent", String.class),
        }));

    }

    //根据订阅者类SubscriberClass为key,SubscriberInfo为value,放入缓存中
    private static void putIndex(SubscriberInfo info) {
        SUBSCRIBER_INDEX.put(info.getSubscriberClass(), info);
    }

    //根据订阅者类SubscriberClass获取SubscriberInfo,再根据SubscriberInfo得到订阅者方法数组SubscriberMethods
    @Override
    public SubscriberInfo getSubscriberInfo(Class<?> subscriberClass) {
        SubscriberInfo info = SUBSCRIBER_INDEX.get(subscriberClass);
        if (info != null) {
            return info;
        } else {
            return null;
        }
    }
}

  1. SubscriberInfoIndex是订阅者信息索引。静态对象SUBSCRIBER_INDEX缓存了订阅者信息SubscriberInfo

  2. 根据@Subscribe得到方法信息和注解携带的参数,得到SubscriberMethodInfo,然后根据SubscriberMethodInfo数组对象构造SimpleSubscriberInfo对象,便于后期调用SubscriberInfo的getSubscriberMethods()得到订阅方法数组

  3. 在调用getSubscriberInfo()时,会根据subcriberClass得到对应的订阅者信息SubscribeInfo

订阅者信息SubscriberInfo用来保存SubscriberClass中包含所有订阅方法的信息
再看下订阅者信息SubscriberInfo

public interface SubscriberInfo {
    Class<?> getSubscriberClass(); //订阅者类SubscriberClass

    SubscriberMethod[] getSubscriberMethods(); //订阅者类内含有的订阅者方法SubscribeMethods

    SubscriberInfo getSuperSubscriberInfo();//得到父类订阅者索引信息 SubscriberInfo,用于向上查找。在SimpleSubscriberInfo中这个值为null

    boolean shouldCheckSuperclass();//是否应该检查父类订阅者索引信息
}

再看AbstractSubscriberInfo对于SubscriberInfo,做了一些基础的实现

public abstract class AbstractSubscriberInfo implements SubscriberInfo {
    private final Class subscriberClass;
    private final Class<? extends SubscriberInfo> superSubscriberInfoClass;
    private final boolean shouldCheckSuperclass;

    protected AbstractSubscriberInfo(Class subscriberClass, Class<? extends SubscriberInfo> superSubscriberInfoClass,
                                     boolean shouldCheckSuperclass) {
        this.subscriberClass = subscriberClass;
        this.superSubscriberInfoClass = superSubscriberInfoClass;
        this.shouldCheckSuperclass = shouldCheckSuperclass;
    }

    @Override
    public Class getSubscriberClass() {
        return subscriberClass;
    }

    //从SimpleSubscriberInfo传过来的为null
    @Override
    public SubscriberInfo getSuperSubscriberInfo() {
        if(superSubscriberInfoClass == null) {
            return null;
        }
        try {
            return superSubscriberInfoClass.newInstance();
        } catch (InstantiationException e) {
            throw new RuntimeException(e);
        } catch (IllegalAccessException e) {
            throw new RuntimeException(e);
        }
    }

    @Override
    public boolean shouldCheckSuperclass() {
        return shouldCheckSuperclass;//默认为true
    }

    //根据methodName和eventType构造出订阅者方法SubscriberMethod,threadMode默认为Posting,priority默认为0,sticky默认为false
    protected SubscriberMethod createSubscriberMethod(String methodName, Class<?> eventType) {
        return createSubscriberMethod(methodName, eventType, ThreadMode.POSTING, 0, false);
    }

    protected SubscriberMethod createSubscriberMethod(String methodName, Class<?> eventType, ThreadMode threadMode) {
        return createSubscriberMethod(methodName, eventType, threadMode, 0, false);
    }

    //真正生成SubscriberMethod的地方,多提取出一个Method对象,然后构造出SubscriberMethod对象
    protected SubscriberMethod createSubscriberMethod(String methodName, Class<?> eventType, ThreadMode threadMode,
                                                      int priority, boolean sticky) {
        try {
            Method method = subscriberClass.getDeclaredMethod(methodName, eventType);
            return new SubscriberMethod(method, eventType, threadMode, priority, sticky);
        } catch (NoSuchMethodException e) {
            throw new EventBusException("Could not find subscriber method in " + subscriberClass +
                    ". Maybe a missing ProGuard rule?", e);
        }
    }

}

再看SimpleSubscriberInfo

public class SimpleSubscriberInfo extends AbstractSubscriberInfo {

    private final SubscriberMethodInfo[] methodInfos;

    public SimpleSubscriberInfo(Class subscriberClass, boolean shouldCheckSuperclass, SubscriberMethodInfo[] methodInfos) {
        super(subscriberClass, null, shouldCheckSuperclass);//这里传给父类的superSubscriberInfoClass为null
        this.methodInfos = methodInfos;
    }

    @Override
    public synchronized SubscriberMethod[] getSubscriberMethods() {
        int length = methodInfos.length;
        SubscriberMethod[] methods = new SubscriberMethod[length];
        for (int i = 0; i < length; i++) {
            SubscriberMethodInfo info = methodInfos[i];
            //根据SubscriberMethodInfo生成SubscriberMethod
            methods[i] = createSubscriberMethod(info.methodName, info.eventType, info.threadMode,
                    info.priority, info.sticky);
        }
        return methods;
    }
}
  1. SubscriberMethodInfo包含方法信息methodName,eventType;注解信息threadMode,priority,sticky

  2. SubscriberInfo调用getSubscriberMethods(),根据遍历SubscriberMethodInfo数组,对每一个SubscriberMethodInfo构造订阅方法SubscribeMethod对象,并且返回

Register

上面分析了怎么通过APT来将@Subscribe注解的信息转换成需要的SubscriberMethod。下面再来分析一下具体的订阅过程

public void register(Object subscriber) {
    Class<?> subscriberClass = subscriber.getClass();//获得订阅者的类对象subscriberClass
    List<SubscriberMethod> subscriberMethods = subscriberMethodFinder.findSubscriberMethods(subscriberClass);//找到对应subscriberClass的订阅者方法List
    synchronized (this) {
        for (SubscriberMethod subscriberMethod : subscriberMethods) {
            subscribe(subscriber, subscriberMethod);//执行订阅
        }
    }
}
  1. 获得订阅者对象的Class,subscriberClass
  2. 获取订阅者类subscriberClass的subscriberMethod的List
  3. 遍历subscriberMethods,对每一个订阅者对象subscriber和订阅方法subscriberMethod执行subscribe()

从上面的三个步骤会发现有2个不了解的东西,subscriberMethodFinder和subscribe()。但是subscriberMethodFinder.findSubscriberMethods()的返回值我们熟悉,根据上面的分析这里返回的就是每个SubscriberClass的所有订阅者方法信息的列表。
然后遍历subscriberMethods,对于每一个subscriberClass和subscriberMethod执行subscribe()

下面先分析subscriberMethodFinder,再介绍SubscriberMethodFinder之前先介绍FindState

FindState

FindState是用来做订阅方法的校验和保存,是

final List<SubscriberMethod> subscriberMethods = new ArrayList<>();//订阅方法的List
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;//订阅者信息
//判断method和对应的eventType能否添加进订阅者类的方法列表
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.
    //先放入anyMethodByEventType里面
    Object existing = anyMethodByEventType.put(eventType, method);
    //如果existing为null,表示不存在冲突,之前没有method方法,响应这个EventType
    if (existing == null) {
        return true;
    } else {
        if (existing instanceof Method) {
            //用MethodSignature校验method和eventType,是否能够添加
            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);
    }
}

//根据MethodSignature来校验method和eventType能否添加,能否订阅对应的Event
//如果订阅方法method,方法名和相应的Event
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();//返回声明此Method对象,表示的方法的类的Class对象,即subscriberClass
    Class<?> methodClassOld = subscriberClassByMethodKey.put(methodKey, methodClass);//之前放入的订阅者类subscriberClass
    //如果之前没放入,或者methodClassOld是methodClass所表示的类或者接口,即methodClass和methodClassOld是同一个类或者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;
        }
    }
}

FindState是用于在查找订阅者类SubscriberClass所对应的SubscriberMethod列表的时候,判断是否能够添加进SubscriberMethod列表的方法

下面有点绕,细想想其实主要是解决父类和子类具有相同的订阅方法的处理,一般可能用不到这些

checkAddWithMethodSignature()方法的意义

  1. 用方法名method.getName()和方法参数的Class类型名eventType.getName()构造成methodKey
  2. 把methodKey做为key,methodClass(即声明此方法的类的Class对象)为value存入subscriberClassByMethodKey
  3. 如果subscriberClassByMethodKey之前没有放入过相同方法签名的订阅者类即(methodClassOld == null) 或者之前的订阅者类methodClassOld是现在methodClass的子类或相同类,那么就表示可以添加
  1. 如果之前没有存在订阅相同Event事件的方法,就表示可以添加
  2. 如果存在订阅相同类型的Event的方法

    2.1 如果existing是Method对象,会先检查existingeventType能否添加进订阅者方法列表

    2.2 如果能够放入订阅方法列表,那么就会把findState对象存入anyMethodByEventType,来消耗之前放入的method

    2.3 如果不能放入则抛异常
  3. 检查当前方法是否能够添加进订阅方法列表,checkAddWithMethodSignature(method, eventType)

SubscriberMethodFinder

先看对象

private static final Map<Class<?>, List<SubscriberMethod>> METHOD_CACHE = new ConcurrentHashMap<>();//方法信息的缓存,对于每一个订阅者类,会把第一次查找到List<SubscriberMethod>缓存起来

private List<SubscriberInfoIndex> subscriberInfoIndexes;//订阅者信息索引SubscriberInfoIndexes列表
private final boolean strictMethodVerification;//严格的方法校验,默认值为false
private final boolean ignoreGeneratedIndex;//强制用反射查找SubscribeMethod,即使生成了订阅者信息索引SubscriberInfoIndex,默认值为false

private static final int POOL_SIZE = 4;//FindState的池子大小
private static final FindState[] FIND_STATE_POOL = new FindState[POOL_SIZE];//FindState池,便于复用

下面看看最重要的方法findSubscriberMethods()

根据订阅者类subscriberClass来查找List<SubscriberMethod>

List<SubscriberMethod> findSubscriberMethods(Class<?> subscriberClass) {
    List<SubscriberMethod> subscriberMethods = METHOD_CACHE.get(subscriberClass);
    //如果缓存里面,直接返回
    if (subscriberMethods != null) {
        return subscriberMethods;
    }

    //默认值为false,推荐用APT技术来做,毕竟反射性能较低
    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 {
        //把找到的subscriberMethods放入缓存
        METHOD_CACHE.put(subscriberClass, subscriberMethods);
        return subscriberMethods;
    }
}
  1. 先查找缓存,如果缓存里面有,说明不是第一次查找,那么直接返回
  2. 如果没有缓存,那么就利用索引或者反射的方法查找subscriberMethods
  3. 把找到的subscriberMethods放入缓存METHOD_CACHE

上面又有两个重要的方法findUsingReflection()和findUsingInfo();优先介绍findUsingInfo(),毕竟是推荐使用的方法

private List<SubscriberMethod> findUsingInfo(Class<?> subscriberClass) {
    FindState findState = prepareFindState();//找到一个可用的空闲的FindState
    findState.initForSubscriber(subscriberClass);//设置FindState的订阅者类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对象里面
                    findState.subscriberMethods.add(subscriberMethod);
                }
            }
        } else {
            //如果用户没有设置SubscrierInfoIndex,或者订阅者信息找不到订阅者信息SubscriberInfo的话,就走反射的方式获取订阅方法列表
            findUsingReflectionInSingleClass(findState);
        }
        //移到基类继续查找
        findState.moveToSuperclass();
    }
    //得到订阅方法列表,并且释放FindState进FIND_STATE_POOL里面
    return getMethodsAndRelease(findState);
}

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;
}

findUsingInfo就是EventBus 3 推荐用的方法,使用APT技术首先生成SubscribeerInfoIndex,提升首次查找订阅者类的相关方法时的性能,如果没有设置索引类,那么就会使用反射方法

  1. 在FIND_STATE_POOL里查找可以复用的FindState,并把相关的订阅者类SubscriberClass设置进去
  2. 根据生成的订阅者信息索引类SubscriberInfoIndex来查找SubscriberInfo。如果没找到就会调用findUsingReflectionInSingleClass()方法,利用反射来查找。
  3. 根据SubscrberInfo拿到所有的订阅者方法SubscriberMethods
  4. 遍历SubscriberMethods,检查是否能够添加进订阅者方法SubscriberMethods,如果通过检查则添加进去
  5. 移动到基类,重复2,3,4步骤
  6. 得到SubscriberMethods列表,并且释放FindState进FIND_STATE_POOL里

下面再看下利用反射来获取SubscriberMethods的过程

private List<SubscriberMethod> findUsingReflection(Class<?> subscriberClass) {
    FindState findState = prepareFindState();
    findState.initForSubscriber(subscriberClass);
    while (findState.clazz != null) {
        //反射获取单个类Class的订阅方法list
        findUsingReflectionInSingleClass(findState);
        //移到基类,继续遍历
        findState.moveToSuperclass();
    }
    //获取subscrberMethods,并且释放findState
    return getMethodsAndRelease(findState);
}

private void findUsingReflectionInSingleClass(FindState findState) {
    Method[] methods;
    try {
        // This is faster than getMethods, especially when subscribers are fat classes like Activities
        methods = findState.clazz.getDeclaredMethods();
    } catch (Throwable th) {
        // Workaround for java.lang.NoClassDefFoundError, see https://github.com/greenrobot/EventBus/issues/149
        methods = findState.clazz.getMethods();
        findState.skipSuperClasses = true;
    }
    //methods是类Class的所有方法,遍历方法数组
    for (Method method : methods) {
        int modifiers = method.getModifiers();
        //修饰符必须为Public,非static,非abstract,非bridge,非synthetic
        if ((modifiers & Modifier.PUBLIC) != 0 && (modifiers & MODIFIERS_IGNORE) == 0) {
            Class<?>[] parameterTypes = method.getParameterTypes();
            //参数长度必须为一个
            if (parameterTypes.length == 1) {
                Subscribe subscribeAnnotation = method.getAnnotation(Subscribe.class);
                //必须要有@Subscriber注解
                if (subscribeAnnotation != null) {
                //获取Event的类型
                    Class<?> eventType = parameterTypes[0];
                    //调用findState的checkAdd(),检查是否可以添加
                    if (findState.checkAdd(method, eventType)) {
                        ThreadMode threadMode = subscribeAnnotation.threadMode();
                        //获取@Subscriber的注解信息,构造出SubscriberMethods,添加进subscriberMethods
                        findState.subscriberMethods.add(new SubscriberMethod(method, eventType, threadMode,
                                subscribeAnnotation.priority(), subscribeAnnotation.sticky()));
                    }
                }
            } else if (strictMethodVerification && method.isAnnotationPresent(Subscribe.class)) {
                String methodName = method.getDeclaringClass().getName() + "." + method.getName();
                throw new EventBusException("@Subscribe method " + methodName +
                        "must have exactly 1 parameter but has " + parameterTypes.length);
            }
        } else if (strictMethodVerification && method.isAnnotationPresent(Subscribe.class)) {
            String methodName = method.getDeclaringClass().getName() + "." + method.getName();
            throw new EventBusException(methodName +
                    " is a illegal @Subscribe method: must be public, non-static, and non-abstract");
        }
    }
}

上面的方法比较清晰
findUsingReflection() 中

  1. 获取当前订阅者类的订阅方法数组subscriberMethods,添加到findState.subscriberMethods对象里
  2. 移动当前订阅者类的基类
  3. 继续查找基类中的订阅者方法SubscriberMethods,添加到findState.subscriberMethods对象里
  4. 获取当前订阅者类(包括基类)的所有订阅方法,并且释放FindState

findUsingReflectionInSingleClass()获取当前订阅者类的所有订阅方法,添加进findState.subscriberMethods

  1. 获取所有方法,并且遍历
  2. 找到符合条件的方法
  3. 根据@Subscribe注解携带的信息,构造SubscriberMethod添加进findState.subscriberMethods

上面的文档算是搞清楚了一件事,怎么找到订阅者类SubscriberClass的订阅方法数组SubscriberMethods;可能是利用APT在编译期首先对@Subscribe进行解析,或者是在运行时利用反射;还涉及到对于父类的订阅方法的查找;检测方法的添加;对@Subscribe注解的解析等。

上面的部分完成了register()方法中subscriberMethodFinder.findSubscriberMethods(subscriberClass);
下面可以继续往下走了,遍历subscriberMethods,继续看subscribe(subscriber, subscriberMethod)方法

public void register(Object subscriber) {
    Class<?> subscriberClass = subscriber.getClass();
    List<SubscriberMethod> subscriberMethods = subscriberMethodFinder.findSubscriberMethods(subscriberClass);
    synchronized (this) {
        for (SubscriberMethod subscriberMethod : subscriberMethods) {
            subscribe(subscriber, subscriberMethod);
        }
    }
}
private void subscribe(Object subscriber, SubscriberMethod subscriberMethod) {
    Class<?> eventType = subscriberMethod.eventType;
    //根据subscriber,subscriberMethod构造Subscription
    Subscription newSubscription = new Subscription(subscriber, subscriberMethod);
    //得到响应这个事件类型eventType所有的订阅者subscriptions
    CopyOnWriteArrayList<Subscription> subscriptions = subscriptionsByEventType.get(eventType);
    if (subscriptions == null) {
        subscriptions = new CopyOnWriteArrayList<>();
        subscriptionsByEventType.put(eventType, subscriptions);
    } else {
        if (subscriptions.contains(newSubscription)) {
            throw new EventBusException("Subscriber " + subscriber.getClass() + " already registered to event "
                    + eventType);
        }
    }

    //对响应这个事件类型EventType的订阅方法进行排序,相同优先级的方法,先注册的在前面
    int size = subscriptions.size();
    for (int i = 0; i <= size; i++) {
        if (i == size || subscriberMethod.priority > subscriptions.get(i).subscriberMethod.priority) {
            subscriptions.add(i, newSubscription);
            break;
        }
    }

    List<Class<?>> subscribedEvents = typesBySubscriber.get(subscriber);
    if (subscribedEvents == null) {
        subscribedEvents = new ArrayList<>();
        typesBySubscriber.put(subscriber, subscribedEvents);
    }
    //订阅者的响应类型添加当前订阅方法的事件类型
    subscribedEvents.add(eventType);

    //如果当前方法响应粘性事件
    if (subscriberMethod.sticky) {
    //是否考虑继承,是否响应继承事件,默认为true
        if (eventInheritance) {
            //响应继承
            //遍历所有类型的粘性事件,给当前订阅者发送所有eventType类型或者基类的事件
            Set<Map.Entry<Class<?>, Object>> entries = stickyEvents.entrySet();
            for (Map.Entry<Class<?>, Object> entry : entries) {
                Class<?> candidateEventType = entry.getKey();
                if (eventType.isAssignableFrom(candidateEventType)) {
                    Object stickyEvent = entry.getValue();
                    checkPostStickyEventToSubscription(newSubscription, stickyEvent);
                }
            }
        } else {
        //不响应继承,直接查找当前eventType的值,然后发送
            Object stickyEvent = stickyEvents.get(eventType);
            checkPostStickyEventToSubscription(newSubscription, stickyEvent);
        }
    }
}
  1. 查找响应相同eventType的所有subscriptions,然后根据方法的优先级插入subscriptions列表,相同优先级的方法,先注册的先响应。
  2. 把eventType插入订阅者的响应的事件列表subscribedEvents里
  3. 判断当前订阅方法是否是粘性方法,如果是粘性方法,那么就发送相应的粘性事件

注册的流程就分析到这了,下面会在分析解注册和事件分发的流程

©著作权归作者所有,转载或内容合作请联系作者
平台声明:文章内容(如有图片或视频亦包括在内)由作者上传并发布,文章内容仅代表作者本人观点,简书系信息发布平台,仅提供信息存储服务。

推荐阅读更多精彩内容