Spring Boot2.0版本源码(三):Spring Boot监听器的实现

1. 介绍监听器的组成部分

springboot的监听器都是通过ApplicationListener实现的类完成对监听事件的处理的,看得出来,所有的监听事件都是ApplicationEvent
在这里插入图片描述
ApplicationEventMulticaster就是管理这些监听器的多播器,里面用一个集合存储了所有的ApplicationListener的实现类,可以实现增加一个监听器,删除一个监听器,和执行所有监听器中的处理监听事件的方法等等。
在这里插入图片描述

1.1 会产生事件的环节

在这里插入图片描述
1.starting:springboot启动的时候发出该事件
2.environmentPrepared:环境准备完成的时候发出该事件,说明环境的一些的属性加载成功
3.contextInitialized:表示spring的上下文准备完成
4.prepared:表示上下文准备完成但是bean还没有完成初始化
5.started:表示当前bean已经实例化完成,但是还没有调用ApplicationRunner
6.ready:表示ApplicationRunner已经调用完成

1.2 监听器的初始化

监听器的初始化也是调用getSpringFactoriesInstances,具体步骤和Spring Boot2.0版本源码(二):Spring Boot初始化器中的初始化器的初始化过程是一样的:

1.通过"META-INF/spring.factories"文件,获得所有的重写了带有ApplicationContextInitializer的全路径名
2.将这些类实例化
3.对这些类排序
在这里插入图片描述

2. 监听器的触发

SpringApplicationrun()方法内,有一行关于listeners.starting()触发监听事件步骤。
在这里插入图片描述
跟进源码
在这里插入图片描述
继续跟进,发现其是调用了springboot的广播器实现对监听事件的调用
在这里插入图片描述
跟进multicastEvent(ApplicationEvent event)方法
1.multicastEvent里面调用了一个同名方法
2.通过getApplicationListeners(event, type)获取对该event感兴趣的事件
3.执行第2步获取的所有的listener

2.2 getApplicationListeners(event, type)源码

/**
	 * Return a Collection of ApplicationListeners matching the given
	 * event type. Non-matching listeners get excluded early.
	 * @param event the event to be propagated. Allows for excluding
	 * non-matching listeners early, based on cached matching information.
	 * @param eventType the event type
	 * @return a Collection of ApplicationListeners
	 * @see org.springframework.context.ApplicationListener
	 */
	protected Collection<ApplicationListener<?>> getApplicationListeners(
			ApplicationEvent event, ResolvableType eventType) {
		// 事件的来源就是SpringbootApplication对象
		Object source = event.getSource();
		Class<?> sourceType = (source != null ? source.getClass() : null);

		ListenerCacheKey cacheKey = new ListenerCacheKey(eventType, sourceType);

		// Quick check for existing entry on ConcurrentHashMap...
		// 从缓冲区中获取event事件感兴趣的监听者
		ListenerRetriever retriever = this.retrieverCache.get(cacheKey);
		if (retriever != null) {
			return retriever.getApplicationListeners();
		}

		if (this.beanClassLoader == null ||
				(ClassUtils.isCacheSafe(event.getClass(), this.beanClassLoader) &&
						(sourceType == null || ClassUtils.isCacheSafe(sourceType, this.beanClassLoader)))) {
			// Fully synchronized building and caching of a ListenerRetriever
			synchronized (this.retrievalMutex) {
				// 双重检验
				retriever = this.retrieverCache.get(cacheKey);
				if (retriever != null) {
					return retriever.getApplicationListeners();
				}
				retriever = new ListenerRetriever(true);
				// retrieveApplicationListeners()方法实现获取eventType事件的监听事件
				Collection<ApplicationListener<?>> listeners =
						retrieveApplicationListeners(eventType, sourceType, retriever);
				// 监听事件放入缓存
				this.retrieverCache.put(cacheKey, retriever);
				return listeners;
			}
		}
		else {
			// No ListenerRetriever caching -> no synchronization necessary
			return retrieveApplicationListeners(eventType, sourceType, null);
		}
	}

跟进核心源码部分:retrieveApplicationListeners()如何获取eventType事件的监听事件
1.遍历所有监听器,通过supportsEvent(listener, eventType, sourceType)方法判断事件和监听器是否关联,将当前事件的关联的监听器全部加入list
2.对list排序

/**
	 * Actually retrieve the application listeners for the given event and source type.
	 * @param eventType the event type
	 * @param sourceType the event source type
	 * @param retriever the ListenerRetriever, if supposed to populate one (for caching purposes)
	 * @return the pre-filtered list of application listeners for the given event and source type
	 */
	private Collection<ApplicationListener<?>> retrieveApplicationListeners(
			ResolvableType eventType, @Nullable Class<?> sourceType, @Nullable ListenerRetriever retriever) {

		// 集合的初始化
		List<ApplicationListener<?>> allListeners = new ArrayList<>();
		Set<ApplicationListener<?>> listeners;
		Set<String> listenerBeans;
		synchronized (this.retrievalMutex) {
			listeners = new LinkedHashSet<>(this.defaultRetriever.applicationListeners);
			listenerBeans = new LinkedHashSet<>(this.defaultRetriever.applicationListenerBeans);
		}

		// Add programmatically registered listeners, including ones coming
		// from ApplicationListenerDetector (singleton beans and inner beans).
		// 遍历所有的监听器,然后
		for (ApplicationListener<?> listener : listeners) {
			// 判断当前监听器是否对listener对event感兴趣
			if (supportsEvent(listener, eventType, sourceType)) {
				if (retriever != null) {
					retriever.applicationListeners.add(listener);
				}
				// 感兴趣的监听器会被加入到allListeners集合中
				allListeners.add(listener);
			}
		}

		// Add listeners by bean name, potentially overlapping with programmatically
		// registered listeners above - but here potentially with additional metadata.
		// listenerBeans默认为空,此处不做解释
		if (!listenerBeans.isEmpty()) {
			ConfigurableBeanFactory beanFactory = getBeanFactory();
			for (String listenerBeanName : listenerBeans) {
				try {
					if (supportsEvent(beanFactory, listenerBeanName, eventType)) {
						ApplicationListener<?> listener =
								beanFactory.getBean(listenerBeanName, ApplicationListener.class);
						if (!allListeners.contains(listener) && supportsEvent(listener, eventType, sourceType)) {
							if (retriever != null) {
								if (beanFactory.isSingleton(listenerBeanName)) {
									retriever.applicationListeners.add(listener);
								}
								else {
									retriever.applicationListenerBeans.add(listenerBeanName);
								}
							}
							allListeners.add(listener);
						}
					}
					else {
						// Remove non-matching listeners that originally came from
						// ApplicationListenerDetector, possibly ruled out by additional
						// BeanDefinition metadata (e.g. factory method generics) above.
						Object listener = beanFactory.getSingleton(listenerBeanName);
						if (retriever != null) {
							retriever.applicationListeners.remove(listener);
						}
						allListeners.remove(listener);
					}
				}
				catch (NoSuchBeanDefinitionException ex) {
					// Singleton listener instance (without backing bean definition) disappeared -
					// probably in the middle of the destruction phase
				}
			}
		}

		// 所有监听器进行排序
		AnnotationAwareOrderComparator.sort(allListeners);
		if (retriever != null && retriever.applicationListenerBeans.isEmpty()) {
			retriever.applicationListeners.clear();
			retriever.applicationListeners.addAll(allListeners);
		}
		return allListeners;
	}

继续跟进:supportsEvent(listener, eventType, sourceType)的源码
1.GenericApplicationListenerAdapter初始化的时候会完成对感兴趣的事件的解析,所以将所有的监听器封装成GenericApplicationListenerAdapter
2.利用supportsEventType()来判断是否对该事件感兴趣,利用supportsSourceType()来判断是否支持该事件的来源

/**
	 * Determine whether the given listener supports the given event.
	 * <p>The default implementation detects the {@link SmartApplicationListener}
	 * and {@link GenericApplicationListener} interfaces. In case of a standard
	 * {@link ApplicationListener}, a {@link GenericApplicationListenerAdapter}
	 * will be used to introspect the generically declared type of the target listener.
	 * @param listener the target listener to check
	 * @param eventType the event type to check against
	 * @param sourceType the source type to check against
	 * @return whether the given listener should be included in the candidates
	 * for the given event type
	 */
	protected boolean supportsEvent(
			ApplicationListener<?> listener, ResolvableType eventType, @Nullable Class<?> sourceType) {
		// 将当前监听器封装成一个GenericApplicationListener
		// GenericApplicationListenerAdapter初始化的时候会完成对感兴趣的事件的解析
		GenericApplicationListener smartListener = (listener instanceof GenericApplicationListener ?
				(GenericApplicationListener) listener : new GenericApplicationListenerAdapter(listener));
		//supportsEventType()来判断是否对该事件感兴趣
		// supportsSourceType()来判断是否支持该事件的来源
		return (smartListener.supportsEventType(eventType) && smartListener.supportsSourceType(sourceType));
	}

2.2.1 GenericApplicationListenerAdapter()的构造函数

/**
	 * Create a new GenericApplicationListener for the given delegate.
	 * @param delegate the delegate listener to be invoked
	 */
	@SuppressWarnings("unchecked")
	public GenericApplicationListenerAdapter(ApplicationListener<?> delegate) {
		Assert.notNull(delegate, "Delegate listener must not be null");
		// 监听器
		this.delegate = (ApplicationListener<ApplicationEvent>) delegate;
		// 计算出感兴趣的事件
		this.declaredEventType = resolveDeclaredEventType(this.delegate);
	}

2.2.2 smartListener.supportsEventType(eventType)源码

1.如果当前监听器是SmartApplicationListener就调用其自身supportsEventType方法判断其是否支持该事件
2.否则判断当前监听器的感兴趣事件和当前的evnetType是否相同

	@Override
	@SuppressWarnings("unchecked")
	public boolean supportsEventType(ResolvableType eventType) {
		// 如果是SmartApplicationListener就调用其自身supportsEventType方法判断其是否支持该事件
		if (this.delegate instanceof SmartApplicationListener) {
			Class<? extends ApplicationEvent> eventClass = (Class<? extends ApplicationEvent>) eventType.resolve();
			return (eventClass != null && ((SmartApplicationListener) this.delegate).supportsEventType(eventClass));
		}
		else {
			// 判断当前监听器的感兴趣事件和当前的evnetType是否相同
			return (this.declaredEventType == null || this.declaredEventType.isAssignableFrom(eventType));
		}
	}

2.2.3 smartListener.supportsSourceType(sourceType))判断事件的来源

1.判断当前监听器不是SmartApplicationListener返回true
2.当前监听器是SmartApplicationListener就调用supportsSourceType方法判断支持该事件的来源

	@Override
	public boolean supportsSourceType(@Nullable Class<?> sourceType) {
		// 如果当前监听器件不是SmartApplicationListener返回true
		// 如果当前监听器是SmartApplicationListener就调用supportsSourceType方法判断支持该事件的来源
		// 说明:实现SmartApplicationListener接口的listener感兴趣的事件都是一个ApplicationEvent这样一个大的监听事件
		//      其他listener感兴趣的事件都会被详细指定
		return !(this.delegate instanceof SmartApplicationListener) ||
				((SmartApplicationListener) this.delegate).supportsSourceType(sourceType);
	}

总结

获取event事件对应的监听器列表
在这里插入图片描述
supportsEvent的逻辑
在这里插入图片描述

发布了275 篇原创文章 · 获赞 42 · 访问量 7万+

猜你喜欢

转载自blog.csdn.net/qq_35688140/article/details/105632308
今日推荐