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);
}
}
}
}
Spring事件分发器ApplicationEventMulticaster分发事件原理
最新推荐文章于 2024-08-30 22:12:39 发布
本文详细解释了Spring框架中的ApplicationContext如何初始化和管理ApplicationEventMulticaster,以及如何通过publishEvent方法发布事件并由ApplicationListener进行处理,包括PayloadApplicationEvent的包装和事件类型的解析过程。
摘要由CSDN通过智能技术生成