springboot 2.2.2 源码详解(四):监听器

​ 在看springboot的源码过程中,发现内部使用了大量的监听器,下面来看下监听器的作用。

在springboot的监听器有如下两类:

# Run Listeners
#事件发布运行监听器,是springboot中配置的唯一一个应用运行监听器,作用是通过一个多路广播器,将springboot运行状态的变化,构建成事件,并广播给各个监听器
org.springframework.boot.SpringApplicationRunListener=\
org.springframework.boot.context.event.EventPublishingRunListener

# Application Listeners
org.springframework.context.ApplicationListener=\
org.springframework.boot.ClearCachesApplicationListener(),\
org.springframework.boot.builder.ParentContextCloserApplicationListener,\
org.springframework.boot.cloud.CloudFoundryVcapEnvironmentPostProcessor,\
org.springframework.boot.context.FileEncodingApplicationListener,\
org.springframework.boot.context.config.AnsiOutputApplicationListener,\
org.springframework.boot.context.config.ConfigFileApplicationListener,\
org.springframework.boot.context.config.DelegatingApplicationListener,\
org.springframework.boot.context.logging.ClasspathLoggingApplicationListener,\
org.springframework.boot.context.logging.LoggingApplicationListener,\
org.springframework.boot.liquibase.LiquibaseServiceLocatorApplicationListener

# Application Listeners
org.springframework.context.ApplicationListener=\
org.springframework.boot.autoconfigure.BackgroundPreinitializer

​ 当程序开始运行的时候,可以看到启动了一个运行时监听器,并且创建了一个SpringApplicationRunListeners对象,该对象是一个封装工具类,封装了所有的启动监听器:代码如下

class SpringApplicationRunListeners {
    
    

	private final Log log;

    //启动类监听器
	private final List<SpringApplicationRunListener> listeners;

	SpringApplicationRunListeners(Log log, Collection<? extends SpringApplicationRunListener> listeners) {
    
    
		this.log = log;
		this.listeners = new ArrayList<>(listeners);
	}
//启动上下文事件监听
	void starting() {
    
    
		for (SpringApplicationRunListener listener : this.listeners) {
    
    
			listener.starting();
		}
	}
//environment准备完毕事件监听
	void environmentPrepared(ConfigurableEnvironment environment) {
    
    
		for (SpringApplicationRunListener listener : this.listeners) {
    
    
			listener.environmentPrepared(environment);
		}
	}
//spring上下文准备完毕事件监听
	void contextPrepared(ConfigurableApplicationContext context) {
    
    
		for (SpringApplicationRunListener listener : this.listeners) {
    
    
			listener.contextPrepared(context);
		}
	}
//上下文配置类加载事件监听
	void contextLoaded(ConfigurableApplicationContext context) {
    
    
		for (SpringApplicationRunListener listener : this.listeners) {
    
    
			listener.contextLoaded(context);
		}
	}
//上下文刷新调用事件
	void started(ConfigurableApplicationContext context) {
    
    
		for (SpringApplicationRunListener listener : this.listeners) {
    
    
			listener.started(context);
		}
	}
//上下文刷新完成,在run方法执行完之前调用该事件
	void running(ConfigurableApplicationContext context) {
    
    
		for (SpringApplicationRunListener listener : this.listeners) {
    
    
			listener.running(context);
		}
	}
//在运行过程中失败调起的事件
	void failed(ConfigurableApplicationContext context, Throwable exception) {
    
    
		for (SpringApplicationRunListener listener : this.listeners) {
    
    
			callFailedListener(listener, context, exception);
		}
	}

	private void callFailedListener(SpringApplicationRunListener listener, ConfigurableApplicationContext context,
			Throwable exception) {
    
    
		try {
    
    
			listener.failed(context, exception);
		}
		catch (Throwable ex) {
    
    
			if (exception == null) {
    
    
				ReflectionUtils.rethrowRuntimeException(ex);
			}
			if (this.log.isDebugEnabled()) {
    
    
				this.log.error("Error handling failed", ex);
			}
			else {
    
    
				String message = ex.getMessage();
				message = (message != null) ? message : "no error message";
				this.log.warn("Error handling failed (" + message + ")");
			}
		}
	}

}

​ 在启动源码的流程中,我们知道不同的方法会在不同的时间点触发执行,然后广播出不同的事件,进入到EventPublishingRunListener类中

public EventPublishingRunListener(SpringApplication application, String[] args) {
    
    
		this.application = application;
		this.args = args;
		this.initialMulticaster = new SimpleApplicationEventMulticaster();
		for (ApplicationListener<?> listener : application.getListeners()) {
    
    
			this.initialMulticaster.addApplicationListener(listener);
		}
	}

​ 在当前类的构造方法中默认创建了SimpleApplicationEventMulticaster类,用来完成创建全局的事件发布功能

@Override
	public void starting() {
    
    
		this.initialMulticaster.multicastEvent(new ApplicationStartingEvent(this.application, this.args));
	}

	@Override
	public void environmentPrepared(ConfigurableEnvironment environment) {
    
    
		this.initialMulticaster
				.multicastEvent(new ApplicationEnvironmentPreparedEvent(this.application, this.args, environment));
	}

	@Override
	public void contextPrepared(ConfigurableApplicationContext context) {
    
    
		this.initialMulticaster
				.multicastEvent(new ApplicationContextInitializedEvent(this.application, this.args, context));
	}

	@Override
	public void contextLoaded(ConfigurableApplicationContext context) {
    
    
		for (ApplicationListener<?> listener : this.application.getListeners()) {
    
    
			if (listener instanceof ApplicationContextAware) {
    
    
				((ApplicationContextAware) listener).setApplicationContext(context);
			}
			context.addApplicationListener(listener);
		}
		this.initialMulticaster.multicastEvent(new ApplicationPreparedEvent(this.application, this.args, context));
	}

	@Override
	public void started(ConfigurableApplicationContext context) {
    
    
		context.publishEvent(new ApplicationStartedEvent(this.application, this.args, context));
	}

	@Override
	public void running(ConfigurableApplicationContext context) {
    
    
		context.publishEvent(new ApplicationReadyEvent(this.application, this.args, context));
	}

	@Override
	public void failed(ConfigurableApplicationContext context, Throwable exception) {
    
    
		ApplicationFailedEvent event = new ApplicationFailedEvent(this.application, this.args, context, exception);
		if (context != null && context.isActive()) {
    
    
			// Listeners have been registered to the application context so we should
			// use it at this point if we can
			context.publishEvent(event);
		}
		else {
    
    
			// An inactive context may not have a multicaster so we use our multicaster to
			// call all of the context's listeners instead
			if (context instanceof AbstractApplicationContext) {
    
    
				for (ApplicationListener<?> listener : ((AbstractApplicationContext) context)
						.getApplicationListeners()) {
    
    
					this.initialMulticaster.addApplicationListener(listener);
				}
			}
			this.initialMulticaster.setErrorHandler(new LoggingErrorHandler());
			this.initialMulticaster.multicastEvent(event);
		}
	}

​ 在进行事件广播的时候,会进入如下方法:

@Override
	public void multicastEvent(final ApplicationEvent event, @Nullable ResolvableType eventType) {
    
    
		ResolvableType type = (eventType != null ? eventType : resolveDefaultEventType(event));
        //获取线程池
		Executor executor = getTaskExecutor();
        //根据事件类型选取需要通知的监听器
		for (ApplicationListener<?> listener : getApplicationListeners(event, type)) {
    
    
			//如果不为空,则异步执行	
            if (executor != null) {
    
    
				executor.execute(() -> invokeListener(listener, event));
			}
			else {
    
    
                //如果为空,则同步执行
				invokeListener(listener, event);
			}
		}
	}

​ 在进行事件广播之前,需要将监听器进行过滤,符合类型的留下,不符合类型的过滤掉

protected Collection<ApplicationListener<?>> getApplicationListeners(
			ApplicationEvent event, ResolvableType eventType) {
    
    

		Object source = event.getSource();
		Class<?> sourceType = (source != null ? source.getClass() : null);
		ListenerCacheKey cacheKey = new ListenerCacheKey(eventType, sourceType);

		// Quick check for existing entry on ConcurrentHashMap...
		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);
				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);
		}
	}

​ 实际处理判断逻辑的类:

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) {
    
    
			if (supportsEvent(listener, eventType, sourceType)) {
    
    
				if (retriever != null) {
    
    
					retriever.applicationListeners.add(listener);
				}
				allListeners.add(listener);
			}
		}

		// Add listeners by bean name, potentially overlapping with programmatically
		// registered listeners above - but here potentially with additional metadata.
		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;
	}

在监听器实例化之前,检查是否符合固定的类型

		protected boolean supportsEvent(
			ApplicationListener<?> listener, ResolvableType eventType, @Nullable Class<?> sourceType) {
    
    
		//判断监听器是否是GenericApplicationListener子类,如不是返回一个GenericApplicationListenerAdapter
		GenericApplicationListener smartListener = (listener instanceof GenericApplicationListener ?
				(GenericApplicationListener) listener : new GenericApplicationListenerAdapter(listener));
		return (smartListener.supportsEventType(eventType) && smartListener.supportsSourceType(sourceType));
	}
public interface GenericApplicationListener extends ApplicationListener<ApplicationEvent>, Ordered {
    
    
	boolean supportsEventType(ResolvableType eventType);
	default boolean supportsSourceType(@Nullable Class<?> sourceType) {
    
    
		return true;
	}
	@Override
	default int getOrder() {
    
    
		return LOWEST_PRECEDENCE;
	}

}

此时可以看到GenericApplicationListener类,该类是spring提供的用于重写匹配监听器事件的接口,如果需要判断的监听器是GenericApplicationListener的子类,说明类型匹配方法已被重现,就调用子类的匹配方法,如果不是,提供一个默认的适配器来匹配GenericApplicationListenerAdapter

	public boolean supportsEventType(ResolvableType eventType) {
    
    
		if (this.delegate instanceof SmartApplicationListener) {
    
    
			Class<? extends ApplicationEvent> eventClass = (Class<? extends ApplicationEvent>) eventType.resolve();
			return (eventClass != null && ((SmartApplicationListener) this.delegate).supportsEventType(eventClass));
		}
		else {
    
    
			return (this.declaredEventType == null || this.declaredEventType.isAssignableFrom(eventType));
		}
	}

可以看到该类最终调用的是declaredEventType.isAssignableFrom(eventType)方法,也就是说,如果我们没有重写监听器匹配方法,那么发布的事件 event 会被监听 event以及监听event的父类的监听器监听到。

猜你喜欢

转载自blog.csdn.net/qq_43186095/article/details/103918290