Spring事件分发器ApplicationEventMulticaster分发事件原理

class ApplicationContext {
    // 默认为SimpleApplicationEventMulticaster
    // 在容器启动的时候,会将ApplicationEventMulticaster初始化
    // 优先使用Spring配置的"applicationEventMulticaster"的Bean
    // 否则创建默认的SimpleApplicationEventMulticaster
    private ApplicationEventMulticaster applicationEventMulticaster;

    /**
     * 发布事件
     *
     * @param event     事件源
     * @param eventType 事件类型
     */
    protected void publishEvent(Object event, @Nullable ResolvableType eventType) {
        // 如果有必要,将事件修饰为ApplicationEvent
        // 有两种情况,一种发布的事件直接就是数据,一种发布的是ApplicationEvent或子类,内部通过source保存了发送的数据
        ApplicationEvent applicationEvent;
        // 情况一,发布的事件是ApplicationEvent类型,通过source保存了数据值
        if (event instanceof ApplicationEvent) {
            applicationEvent = (ApplicationEvent) event;
        }
        // 如果事件类型不是ApplicationEvent类型,包装成PayloadApplicationEvent
        // 情况二,发布的事件直接是值,将值封装成PayloadApplicationEvent事件对象,它将当前ApplicationContext作为source,值单独保存到payload中
        else {
            applicationEvent = new PayloadApplicationEvent<>(this, event);
            // 如果没有传入指定的事件类型
            if (eventType == null) {
                // 根据参数推断事件类型
                eventType = ((PayloadApplicationEvent<?>) applicationEvent).getResolvableType() {
                    // 获取发布的值
                    ResolvableType type = ResolvableType.forInstance(getPayload()) {
                        // 如果发布的值是ResolvableTypeProvider类型
                        if (instance instanceof ResolvableTypeProvider) {
                            // 获取ResolvableTypeProvider提供的类型
                            ResolvableType type = ((ResolvableTypeProvider) instance).getResolvableType();
                            // 如果提供了,直接返回
                            if (type != null) {
                                return type;
                            }
                        }
                        // 其他情况,根据发布的值的类型来创建一个新的ResolvableType返回
                        return ResolvableType.forClass(instance.getClass()) {
                            return new ResolvableType(clazz);
                            {
                                // 数据的类型,Class
                                this.resolved = (clazz != null ? clazz : Object.class);
                                // 数据的类型,Type
                                this.type = this.resolved;
                            }
                        }
                    }
                    // getClass = PayloadApplicationEvent
                    // type = ResolvableType[],其实只有一个泛型,是PayloadApplicationEvent泛型参数<T>对应的值,也就是payload数据的值
                    // 根据参数类型解析,最终封装成ResolvableType对象
                    return ResolvableType.forClassWithGenerics(getClass() {
                        return PayloadApplicationEvent.class;
                    },type){
                        // 获取到事当前事件对象PayloadApplicationEvent的泛型参数
                        TypeVariable<?>[] variables = clazz.getTypeParameters();
                        // 泛型参数个数一定要和给定的具体类型数量一致
                        Assert.isTrue(variables.length == generics.length, "Mismatched number of generics specified");
                        // 开始解析参数
                        Type[] arguments = new Type[generics.length];
                        for (int i = 0; i < generics.length; i++) {
                            // 获取到传递过来解析好的具体类型,解析后的ResolvableType,内部包含的是payload的类型信息
                            ResolvableType generic = generics[i];
                            // 如果不为null,获取解析过的类型,否则为null
                            Type argument = (generic != null ? generic.getType() : null);
                            // 如果参数不是TypeVariable(泛型类变量),那么直接当做参数事件
                            // 如果参数是TypeVariable类型,则使用解析后从事件PayloadApplicationEvent中的泛型类型T作为参数
                            arguments[i] = (argument != null && !(argument instanceof TypeVariable) ? argument : variables[i]);
                        }
                        // arguments: 解析好的泛型对应的真实类型
                        // clazz: 事件类型,也就是PayloadApplicationEvent
                        // 包装成SyntheticParameterizedType对象
                        ParameterizedType syntheticType = new SyntheticParameterizedType(clazz, arguments);
                        // 封装成ResolvableType返回
                        return forType(syntheticType, new TypeVariablesVariableResolver(variables, generics)) {
                            // 将事件类型,解析之后的参数类型,泛型变量解析器,封装成ResolvableType返回
                            ResolvableType resultType = new ResolvableType(syntheticType, null, variableResolver);
                            {
                                // 此时的ParameterizedType是将事件类型PayloadApplicationEvent和泛型类型对应的真实类型封装的对象
                                this.type = type;
                                this.resolved = null;
                            }
                        }
                    }
                }
            }
        }
        // 如果存在提早发布的事件,正常下都是为null,是类中私有变量,这是Spring框架自身负责管理和处理,用户无法正常操作这个变量
        if (this.earlyApplicationEvents != null) {
            // 保存当前事件,立即发布
            this.earlyApplicationEvents.add(applicationEvent);
        } else {
            // 使用当前事件派发器分发事件
            getApplicationEventMulticaster().multicastEvent(applicationEvent, eventType) {
                // 获取到解析后的事件类型,上面会传递过来
                // 有两种情况,一种是直接传递的值,如果直接传递了值,上面就会解析得到eventType
                // 一种是直接传递ApplicationEvent,此时eventType为null,使用默认的事件,直接使用ApplicationEvent作为数据的类型
                ResolvableType type = (eventType != null ? eventType : resolveDefaultEventType(event)
                {
                    // 统统将事件处理为具体的ApplicationEvent类型
                    return ResolvableType.forInstance(event);
                });
                // 获取任务执行线程池
                Executor executor = getTaskExecutor() {
                    // 默认SimpleApplicationEventMulticaster没有设置线程池
                    return this.taskExecutor;
                }
                // 根据类型,匹配所有符合当前类型的监听器,然后遍历执行
                Collection<ApplicationListener<?>> listeners = getApplicationListeners(event, type) {
                    // 获取事件对象中的数据类型
                    // 有两种情况,一种是传递的值,此时event是PayloadApplicationEvent类型,其中source是ApplicationContext对象
                    // 另一种情况就是传递的是ApplicaitonEvent对象,则source就是用户指定的数据
                    Object source = event.getSource();
                    // 获取事件对象中数据的数据类型
                    Class<?> sourceType = (source != null ? source.getClass() : null);
                    // 获取缓存key,防止多次查找
                    // 使用事件类型+事件数据参数类型作为Key
                    ListenerCacheKey cacheKey = new ListenerCacheKey(eventType, sourceType);
                    // 查询是否缓存当当前事件类型以
                    ListenerRetriever retriever = this.retrieverCache.get(cacheKey);
                    if (retriever != null) {
                        // 检索监听器
                        return retriever.getApplicationListeners() {
                            // 所有的监听器,因为有的是对象,有的是beanName
                            List<ApplicationListener<?>> allListeners = new ArrayList<>(this.applicationListeners.size() + this.applicationListenerBeans.size());
                            // 添加是对象的ApplicationListener
                            allListeners.addAll(this.applicationListeners);
                            // 如果Listener的BeanName不为空
                            if (!this.applicationListenerBeans.isEmpty()) {
                                // 获取bean工厂
                                BeanFactory beanFactory = getBeanFactory();
                                // 遍历所有的beanName
                                for (String listenerBeanName : this.applicationListenerBeans) {
                                    // 从容器中获取对应的Bean
                                    ApplicationListener<?> listener = beanFactory.getBean(listenerBeanName, ApplicationListener.class);
                                    // 是否需要提前过滤,或者当前获取Listener的对象没有保存的到listener,如果保存了,表示重复了
                                    if (this.preFiltered || !allListeners.contains(listener)) {
                                        allListeners.add(listener);
                                    }
                                }
                            }
                            // 如果不需要提前过滤,或者存在beanName对应的Listener,就要对linstener排序
                            // Listener添加的方法有两种,使用对象形式或者beanName形式保存的Listener
                            // 如果是beanName形式,那么从容器中获取出来的bean是没有顺序的,所以需要统一排序一下
                            if (!this.preFiltered || !this.applicationListenerBeans.isEmpty()) {
                                // 对所有的linstener排序
                                AnnotationAwareOrderComparator.sort(allListeners);
                            }
                            // 返回所有的Listener
                            return allListeners;
                        }
                    }
                    // 如果可以安全的对listener进行缓存
                    if (this.beanClassLoader == null || (ClassUtils.isCacheSafe(event.getClass(), this.beanClassLoader) && (sourceType == null || ClassUtils.isCacheSafe(sourceType, this.beanClassLoader)))) {
                        // 加锁,准备缓存获取到的Listener
                        synchronized (this.retrievalMutex) {
                            // 获取到缓存的retriever的缓存,它里面才包含了对应类型的监听器
                            retriever = this.retrieverCache.get(cacheKey);
                            // 如果retriever缓存了,直接获取监听器
                            if (retriever != null) {
                                // 所有检索器检索监听器对象,上面有此方法的详解
                                return retriever.getApplicationListeners();
                            }
                            // 如果没有被缓存,创建一个新的retriever对象
                            retriever = new ListenerRetriever(true);
                            // 在Spring容器中,找到符合事件类型和资源类型的监听器对象
                            // 并将监听器保存到retriever中,检索ApplicationListener
                            Collection<ApplicationListener<?>> listeners = retrieveApplicationListeners(eventType, sourceType, retriever)
                            {
                                // 所有的listener
                                List<ApplicationListener<?>> allListeners = new ArrayList<>();
                                // 对象形式的listener
                                Set<ApplicationListener<?>> listeners;
                                // beanName形式的listener
                                Set<String> listenerBeans;
                                synchronized (this.retrievalMutex) {
                                    // 在事件分发器中,所有添加的listener都是存在defaultRetriever默认的检索器中
                                    listeners = new LinkedHashSet<>(this.defaultRetriever.applicationListeners);
                                    listenerBeans = new LinkedHashSet<>(this.defaultRetriever.applicationListenerBeans);
                                }
                                // 遍历添加的所有listeners监听器对象
                                for (ApplicationListener<?> listener : listeners) {
                                    // 校验当前监听是是否支持当前事件类型以及事件参数类型
                                    if (supportsEvent(listener, eventType, sourceType) {
                                        GenericApplicationListener smartListener = (listener instanceof GenericApplicationListener ? (GenericApplicationListener) listener : new GenericApplicationListenerAdapter(listener));
                                        // eventType:有两种情况
                                        // 1.1. 一种是直接传递的值,如果直接传递了值,eventType是PayloadApplicationEvent事件对象,它将当前ApplicationContext作为source,值单独保存到payload中
                                        // 2.1. 如果事件类型不是ApplicationEvent类型,包装成PayloadApplicationEvent
                                        // 2.2. 一种是直接传递ApplicationEvent,此时eventType存的类型为就是具体的ApplicationEvent实例,source也就是ApplicationEvent内部保存的source
                                        // 这里进行事件的匹配以及数据的类型匹配
                                        // 简单来说,发布的事件是值,eventType就是泛型上写的类型,source就是ApplicationContext
                                        // 发布的事件是ApplicationEvent,那么eventType是ApplicationEvent对象本身,source是ApplicationEvent内部的对象本身
                                        return (smartListener.supportsEventType(eventType) && smartListener.supportsSourceType(sourceType));

                                    }){
                                        // 如果支持事件+参数类型
                                        // 如果检索器存在,上面会传递指定的检索器,所以不为空
                                        if (retriever != null) {
                                            // 将当前符合事件类型和参数类型的监听器保存到给定的检索器中
                                            retriever.applicationListeners.add(listener);
                                        }
                                        // 同时添加到allListeners所有的监听器中
                                        allListeners.add(listener);
                                    }
                                }

                                // 如果存在listener对应的beanName
                                if (!listenerBeans.isEmpty()) {
                                    // 获取bean工厂
                                    ConfigurableBeanFactory beanFactory = getBeanFactory();
                                    // 遍历所有的beanName listener
                                    for (String listenerBeanName : listenerBeans) {
                                        // 前提判断,当前监听器是否支持当前事件类型,事件类型保存的就是ApplicationListener中的泛型类型
                                        if (supportsEvent(beanFactory, listenerBeanName, eventType) {
                                            // 获取到listener类型
                                            Class<?> listenerType = beanFactory.getType(listenerBeanName);
                                            // 如果listener是这两种监听器类型,暂时放行,下面还要再次校验
                                            if (listenerType == null || GenericApplicationListener.class.isAssignableFrom(listenerType) || SmartApplicationListener.class.isAssignableFrom(listenerType)) {
                                                return true;
                                            }
                                            // 如果不支持,直接返回false
                                            if (!supportsEvent(listenerType, eventType) {
                                                // 获取到ApplicationListener中泛型声明的类型
                                                ResolvableType declaredEventType = GenericApplicationListenerAdapter.resolveDeclaredEventType(listenerType);
                                                // declaredEventType几乎不会为null,因为ApplicationListener都有泛型,如果有泛型,判断声明的泛型类型和事件类型中的eventType中的类型是否匹配
                                                // isAssignableFrom这个不是java的方法,是spring中ResolvableType中的方法
                                                // 是判断eventType中保存的参数类型与Listener中声明是否一致
                                                // 简单来说,发布的事件是值,eventType就是泛型上写的类型,source就是ApplicationContext
                                                // 发布的事件是ApplicationEvent,那么eventType是ApplicationEvent对象本身,source是ApplicationEvent内部的对象本身
                                                return (declaredEventType == null || declaredEventType.isAssignableFrom(eventType));
                                            }){
                                                return false;
                                            }
                                            try {
                                                // 上面都支持,最后判断BeanDefinition
                                                BeanDefinition bd = beanFactory.getMergedBeanDefinition(listenerBeanName);
                                                // 获取到监听器BD对应的Class的泛型类型
                                                ResolvableType genericEventType = bd.getResolvableType().as(ApplicationListener.class).getGeneric();
                                                // 判断BD保存的的监听器类型的泛型参数是不是也符合eventType保存的类型
                                                return (genericEventType == ResolvableType.NONE || genericEventType.isAssignableFrom(eventType));
                                            } catch (NoSuchBeanDefinitionException ex) {
                                                // 如果抛出异常,不存在Bean,就没必要校验,直接支持
                                                return true;
                                            }
                                        }){
                                            // 如果支持当前事件类型
                                            // 先获取到listener对象
                                            ApplicationListener<?> listener = beanFactory.getBean(listenerBeanName, ApplicationListener.class);
                                            // 如果没有保存到allListeners集合中,校验事件类型和数据的类型
                                            // 简单来说,发布的事件是值,eventType就是泛型上写的类型,source就是ApplicationContext
                                            // 发布的事件是ApplicationEvent,那么eventType是ApplicationEvent对象本身,source是ApplicationEvent内部的对象本身
                                            // supportsEvent(listener, eventType, sourceType)三个参数的校验方法,上面有详解
                                            // 监听器支持的事件类型和数据的类型都需要一致才符合要求
                                            if (!allListeners.contains(listener) && supportsEvent(listener, eventType, sourceType)) {
                                                // 上面创建了,不会为空
                                                if (retriever != null) {
                                                    // 如果已经注册成Bean了
                                                    if (beanFactory.isSingleton(listenerBeanName)) {
                                                        // 直接保存当前监听器对象
                                                        retriever.applicationListeners.add(listener);
                                                    } else {
                                                        // 保存监听器的beanName
                                                        retriever.applicationListenerBeans.add(listenerBeanName);
                                                    }
                                                }
                                                // 将获取符合条件的Listener对象保存
                                                allListeners.add(listener);
                                            }
                                        } else{
                                            // 如果当前监听器不支持处理该事件
                                            // 将所有监听器中,不符合条件的监听器移除
                                            Object listener = beanFactory.getSingleton(listenerBeanName);
                                            // 如果存在检索器
                                            if (retriever != null) {
                                                // 将当前不符合条件的监听器移除
                                                retriever.applicationListeners.remove(listener);
                                            }
                                            // 从所有的监听器中也移除
                                            allListeners.remove(listener);
                                        }

                                    }
                                }
                                // 对找到所有符合条件的监听器进行排序
                                AnnotationAwareOrderComparator.sort(allListeners);
                                // 如果存在检索器,并且不存在beanName形式的listener
                                if (retriever != null && retriever.applicationListenerBeans.isEmpty()) {
                                    // 清空applicationListeners
                                    retriever.applicationListeners.clear();
                                    // 将符合条件的监听器保存到retriever检索器中,下面会缓存
                                    retriever.applicationListeners.addAll(allListeners);
                                }
                                return allListeners;
                            }
                            // 将retriever缓存起来,将事件类型和数据类作为Key,检索器作为value,而检索器中包含了符合条件的监听器
                            this.retrieverCache.put(cacheKey, retriever);
                            return listeners;
                        }
                    } else {
                        // 不能安全的进行缓存的话,每次都重新获取符合添加的监听器,上面有检索原理
                        return retrieveApplicationListeners(eventType, sourceType, null);
                    }
                }
                // 遍历所有符合条件的监听器
                for (ApplicationListener<?> listener : listeners) {
                    // 是否存在线程池
                    if (executor != null) {
                        // 使用线程池执行
                        executor.execute(() -> invokeListener(listener, event));
                    } else {
                        // 直接执行
                        invokeListener(listener, event) {
                            // 获取错误的处理器,如果发生错误,使用处理器处理
                            ErrorHandler errorHandler = getErrorHandler() {
                                return this.errorHandler;
                            }
                            // 如果存在错误处理器
                            if (errorHandler != null) {
                                try {
                                    // 发生错误的情况下,捕捉异常,使用错误处理器处理
                                    // 否正常执行
                                    doInvokeListener(listener, event);
                                } catch (Throwable err) {
                                    // 使用异常处理器处理
                                    errorHandler.handleError(err);
                                }
                            } else {
                                // 没有错误处理器,直接执行,有异常则抛出
                                doInvokeListener(listener, event){
                                    // 回调监听器的onApplicationEvent方法
                                    listener.onApplicationEvent(event);
                                }
                            }
                        }
                    }
                }
            }
        }
        // 如果存在父容器
        if (this.parent != null) {
            // 还要将事件分发到父容器中,让父容器中的监听器也同时监听到
            if (this.parent instanceof AbstractApplicationContext) {
                ((AbstractApplicationContext) this.parent).publishEvent(event, eventType);
            } else {
                this.parent.publishEvent(event);
            }
        }
    }
}

  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值