• SpringBoot启动分析2:SpringApplicationRunListeners初始化


    当SpringApplication初始化完毕后,就开始调用实际的run方法执行其他初始化了。

    本地分析SpringApplicationRunListeners的初始化过程,源码如下:

    SpringApplicationRunListeners listeners = getRunListeners(args);
    listeners.starting();
    

    1.1 初始化EventPublishingRunListener

    EventPublishingRunListener是SpringApplicationRunListener的实现,是实际用于发布SpringApplicationEvent类型的事件的实现类。点击getRunListeners跟进源码:

    private SpringApplicationRunListeners getRunListeners(String[] args) {
    	Class<?>[] types = new Class<?>[] { SpringApplication.class, String[].class };
    	return new SpringApplicationRunListeners(logger,
    			getSpringFactoriesInstances(SpringApplicationRunListener.class, types, this, args));
    }
    

    依然是调用通用的方法getSpringFactoriesInstances根据对应的类型来读取spring.factories中的实现:

    org.springframework.boot.SpringApplicationRunListener=
    org.springframework.boot.context.event.EventPublishingRunListener
    

    需要注意的是除了类型参数(SpringApplicationRunListener),还包含已经初始化好的SpringApplication和String类。SpringApplication参数是为了获取内部已通过spring.factories中读取的Listener。
    从之前的getSpringFactoriesInstances方法可知读取到对应的EventPublishingRunListener实现后会对该实现类进行实例化,以下跟进EventPublishingRunListener的构造方法:

    public class EventPublishingRunListener implements SpringApplicationRunListener, Ordered {
    
    	private final SpringApplication application;
    	private final String[] args;
    	private final SimpleApplicationEventMulticaster initialMulticaster;
    
    	public EventPublishingRunListener(SpringApplication application, String[] args) {
    		this.application = application;
    		this.args = args;
    		// 对initialMulticaster进行实例化
    		this.initialMulticaster = new SimpleApplicationEventMulticaster();
    		// SpringApplication参数的作用体现出来了,用于遍历listeners
    		for (ApplicationListener<?> listener : application.getListeners()) {
    			this.initialMulticaster.addApplicationListener(listener);
    		}
    	}
    }	
    

    这里将initialMulticaster变量进行初始化实例,最终通过该实例调用其抽象类AbstractApplicationEventMulticaster的addApplicationListener方法将SpringApplication初始化时的Listeners一个个加入到其中,点击addApplicationListener跟进源码:

    public abstract class AbstractApplicationEventMulticaster implements ApplicationEventMulticaster, BeanClassLoaderAware, BeanFactoryAware {
    
    	private final ListenerRetriever defaultRetriever = new ListenerRetriever(false);
    	final Map<ListenerCacheKey, ListenerRetriever> retrieverCache = new ConcurrentHashMap<>(64);
    	private Object retrievalMutex = this.defaultRetriever;
    
    	@Override
    	public void addApplicationListener(ApplicationListener<?> listener) {
    		synchronized (this.retrievalMutex) {
    			Object singletonTarget = AopProxyUtils.getSingletonTarget(listener);
    			if (singletonTarget instanceof ApplicationListener) {
    				this.defaultRetriever.applicationListeners.remove(singletonTarget);
    			}
    			this.defaultRetriever.applicationListeners.add(listener);
    			this.retrieverCache.clear();
    		}
    	}
    }
    private class ListenerRetriever {
          public final Set<ApplicationListener<?>> applicationListeners = new LinkedHashSet<>();
    	  ......
    }	
    

    在ListenerRetriever中维护着一个Set集合,该Set集合存放着从SpringApplication中获取到的listeners集合,它的作用在于后续遍历监听器,判断监听器是否支持某个事件提供了数据源。

    1.2 筛选支持指定事件的Listener

    当EventPublishingRunListener初始化完成后,调用其starting方法开始根据指定的事件遍历Listener是否支持该指定事件:

    class SpringApplicationRunListeners {
    	void starting() {
    		for (SpringApplicationRunListener listener : this.listeners) {
    			listener.starting();
    		}
    	}
    }	
    public class EventPublishingRunListener implements SpringApplicationRunListener, Ordered {
    
    	@Override
    	public void starting() {
    		this.initialMulticaster.multicastEvent(new ApplicationStartingEvent(this.application, this.args));
    	}
    }
    

    可以看出该指定事件为ApplicationStartingEvent,需要注意的是本次判断一个listener是否支持某个事件指的就是ApplicationStartingEvent
    点击multicastEvent跟进源码,这里主要将对应的事件包装成ResolvableType类型,遍历listeners,对于支持ApplicationStartingEvent事件的listener调用其内部的onApplicationEvent方法:

    public class SimpleApplicationEventMulticaster extends AbstractApplicationEventMulticaster {
    
    	@Override
    	public void multicastEvent(ApplicationEvent event) {
    		// 这里将event包装成ResolvableType
    		multicastEvent(event, resolveDefaultEventType(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); 
    			}
    		}
    	}
    }
    

    获取对事件支持的监听器,核心方法在于getApplicationListeners,这里遍历了Listeners,判断每个Listener是否支持指定的事件(即ApplicationStartingEvent),点击getApplicationListeners跟进源码:

    public abstract class AbstractApplicationEventMulticaster implements ApplicationEventMulticaster, BeanClassLoaderAware, BeanFactoryAware {
    
    	private final ListenerRetriever defaultRetriever = new ListenerRetriever(false);
    	final Map<ListenerCacheKey, ListenerRetriever> retrieverCache = new ConcurrentHashMap<>(64);
    	@Nullable
    	private ClassLoader beanClassLoader;
    	private Object retrievalMutex = this.defaultRetriever;
    	
    	protected Collection<ApplicationListener<?>> getApplicationListeners(ApplicationEvent event, ResolvableType eventType) {
    		Object source = event.getSource();
    		Class<?> sourceType = (source != null ? source.getClass() : null);
    		// 将事件类型和启动类作为参数包装成一个ListenerCacheKey作为缓存key
    		ListenerCacheKey cacheKey = new ListenerCacheKey(eventType, sourceType);
    		// 从缓存获取支持事件的监听器,由于之前没有初始化过retrieverCache所以这里并获取不到
    		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)))) {
    			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 {
    			return retrieveApplicationListeners(eventType, sourceType, null);
    		}
    	}
    }
    

    启动时的初始化是不存在缓存的,所以进入retrieveApplicationListeners方法跟进源码:

    public abstract class AbstractApplicationEventMulticaster implements ApplicationEventMulticaster, BeanClassLoaderAware, BeanFactoryAware {
    
    	private final ListenerRetriever defaultRetriever = new ListenerRetriever(false);
    	final Map<ListenerCacheKey, ListenerRetriever> retrieverCache = new ConcurrentHashMap<>(64);
    	private Object retrievalMutex = this.defaultRetriever;
    
    	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) {
    			// defaultRetriever就是初始化EventPublishingRunListener时调用父类AbstractApplicationEventMulticaster的addApplicationListener方法对其进行初始化
    			listeners = new LinkedHashSet<>(this.defaultRetriever.applicationListeners);
    			listenerBeans = new LinkedHashSet<>(this.defaultRetriever.applicationListenerBeans);
    		}
    
    		// 遍历每个监听器,之前说的ListenerRetriever中维护着一个Set集合就是为此提供了数据源
    		for (ApplicationListener<?> listener : listeners) {
    			// 实际判断监听器是否支持事件的方法
    			if (supportsEvent(listener, eventType, sourceType)) {
    				if (retriever != null) {
    					retriever.applicationListeners.add(listener);
    				}
    				allListeners.add(listener);
    			}
    		}
    		...... // 省略
    		// 对监听器进行排序,为了监听器的执行顺序
    		AnnotationAwareOrderComparator.sort(allListeners);
    		if (retriever != null && retriever.applicationListenerBeans.isEmpty()) {
    			retriever.applicationListeners.clear();
    			retriever.applicationListeners.addAll(allListeners);
    		}
    		return allListeners;
    	}
    }
    

    最终判断监听器是否支持某种事件类型是通过supportsEvent方法来进行,点击supportsEvent跟进源码:

    public abstract class AbstractApplicationEventMulticasterimplements ApplicationEventMulticaster, BeanClassLoaderAware, BeanFactoryAware {
    
    	protected boolean supportsEvent(
    			ApplicationListener<?> listener, ResolvableType eventType, @Nullable Class<?> sourceType) {
    		// 判断listener是否属于GenericApplicationListener类型转换不同的适配,用于根据不同适配调用对应的用于判断是否支持某个事件类型的supportsEventType方法
    		GenericApplicationListener smartListener = (listener instanceof GenericApplicationListener ?
    				(GenericApplicationListener) listener : new GenericApplicationListenerAdapter(listener));
    		return (smartListener.supportsEventType(eventType) && smartListener.supportsSourceType(sourceType));
    	}
    }
    

    这里分为以下两种情况:
    - 若属于GenericApplicationListener的子类则通过GenericApplicationListener父类调用自身的supportsEventType方法判断自己是否支持此事件
    - 若不属于GenericApplicationListener的子类则通过GenericApplicationListenerAdapter统一判断listener是否支持此事件

    1.2.1 情况一:属于GenericApplicationListener的子类

    以LoggingApplicationListener为例,它是属于GenericApplicationListener的子类,类简要定义如下:

    public class LoggingApplicationListener implements GenericApplicationListener {
    
    	private static final Class<?>[] EVENT_TYPES = { 
    		ApplicationStartingEvent.class
    	  , ApplicationEnvironmentPreparedEvent.class
    	  , ApplicationPreparedEvent.class
    	  , ContextClosedEvent.class
    	  , ApplicationFailedEvent.class };
    	private static final Class<?>[] SOURCE_TYPES = { SpringApplication.class, ApplicationContext.class };
    
    	@Override
    	public boolean supportsEventType(ResolvableType resolvableType) {
    		// 通过父类调用本身的supportsEventType方法校验支持的事件
    		return isAssignableFrom(resolvableType.getRawClass(), EVENT_TYPES);
    	}
    	
    	// 最终的校验方法
    	private boolean isAssignableFrom(Class<?> type, Class<?>... supportedTypes) {
    		if (type != null) {
    			for (Class<?> supportedType : supportedTypes) {
    				if (supportedType.isAssignableFrom(type)) {
    					return true;
    				}
    			}
    		}
    		return false;
    	}
    }
    

    从常量EVENT_TYPES定义的该listener支持的事件类型就可以判断出它是支持ApplicationStartingEvent事件。

    1.2.2 情况二:不属于GenericApplicationListener的子类

    不属于GenericApplicationListener的子类则是实例化出new GenericApplicationListenerAdapter(listener)),进入GenericApplicationListenerAdapter构造:

    public class GenericApplicationListenerAdapter implements GenericApplicationListener, SmartApplicationListener {
    
    	private final ApplicationListener<ApplicationEvent> delegate;
    	@Nullable
    	private final ResolvableType declaredEventType;
    
    	public GenericApplicationListenerAdapter(ApplicationListener<?> delegate) {
    		Assert.notNull(delegate, "Delegate listener must not be null");
    		this.delegate = (ApplicationListener<ApplicationEvent>) delegate;
    		// 这里解析出listener的实际泛型事件并包装成ResolvableType,待后续通过该adapter调用其supportsEventType判断是否支持时间时有用
    		this.declaredEventType = resolveDeclaredEventType(this.delegate);
    	}
    	
    	@Nullable
    	private static ResolvableType resolveDeclaredEventType(ApplicationListener<ApplicationEvent> listener) {
    		ResolvableType declaredEventType = resolveDeclaredEventType(listener.getClass());
    		if (declaredEventType == null || declaredEventType.isAssignableFrom(ApplicationEvent.class)) {
    			Class<?> targetClass = AopUtils.getTargetClass(listener);
    			if (targetClass != listener.getClass()) {
    				declaredEventType = resolveDeclaredEventType(targetClass);
    			}
    		}
    		return declaredEventType;
    	}
    	
    	@Nullable
    	static ResolvableType resolveDeclaredEventType(Class<?> listenerType) {
    		ResolvableType eventType = eventTypeCache.get(listenerType);
    		if (eventType == null) {
    			eventType = ResolvableType.forClass(listenerType).as(ApplicationListener.class).getGeneric();
    			eventTypeCache.put(listenerType, eventType);
    		}
    		return (eventType != ResolvableType.NONE ? eventType : null);
    	}
    }
    

    可以看出这种方式就是对于每个不属于GenericApplicationListener子类的listener都创建一个GenericApplicationListenerAdapter对象,根据listener获取其支持的事件并对内部属性进行初始化;
    后续调用GenericApplicationListenerAdapter对象的supportsEventType方法判断是否支持某个事件时GenericApplicationListenerAdapter对象就能获取到该listener已解析过的支持的事件类型:

    public class GenericApplicationListenerAdapter implements GenericApplicationListener, SmartApplicationListener {
    
    	@Override
    	@SuppressWarnings("unchecked")
    	public boolean supportsEventType(ResolvableType eventType) {
    		// 根据是否是属于SmartApplicationListener类型的实例执行不同的判断
    		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));
    		}
    	}
    }	
    

    可以看出这里又分为两种情况:

    • listener属于SmartApplicationListener的子类
    • listener不属于SmartApplicationListener的子类

    不属于SmartApplicationListener子类

    若listener非SmartApplicationListener子类则进入else方法,else方法体中的declaredEventType属性是在初始化GenericApplicationListenerAdapter时就被解析出了事件类型所包装的对象。
    例如CloudFoundryVcapEnvironmentPostProcessor,它的定义如下:

    public class CloudFoundryVcapEnvironmentPostProcessor implements EnvironmentPostProcessor, Ordered, ApplicationListener<ApplicationPreparedEvent> {}
    

    所以以上的declaredEventType属性在CloudFoundryVcapEnvironmentPostProcessor被解析事件类型后解析出来的为ApplicationPreparedEvent事件,最终isAssignableFrom方法是这么判断该listener是否支持事件:

    if (ourResolved == null) {
    	// listener支持的事件,CloudFoundryVcapEnvironmentPostProcessor支持ApplicationPreparedEvent事件
    	ourResolved = resolve(Object.class);
    }
    Class<?> otherResolved = other.toClass();
    // otherResolved是实际需要支持的事件,这里初始化的事件为ApplicationStartingEvent
    if (exactMatch ? !ourResolved.equals(otherResolved) : !ClassUtils.isAssignable(ourResolved, otherResolved)) {
    	return false;
    }
    

    所以CloudFoundryVcapEnvironmentPostProcessor并不支持ApplicationStartingEvent事件,所以本次初始化它的onApplicationEvent并不会得到执行。

    属于SmartApplicationListener子类

    若listener属于SmartApplicationListener子类则进入if方法,例如ConfigFileApplicationListener,它的简要类定义如下:

    public class ConfigFileApplicationListener implements EnvironmentPostProcessor, SmartApplicationListener, Ordered {
    	@Override
    	public boolean supportsEventType(Class<? extends ApplicationEvent> eventType) {
    		return ApplicationEnvironmentPreparedEvent.class.isAssignableFrom(eventType)
    				|| ApplicationPreparedEvent.class.isAssignableFrom(eventType);
    	}
    }
    

    对于属于SmartApplicationListener的子类,则是将listener转换成父类,通过调用父类的supportsEventType方法达到调用自身supportsEventType方法来做判断,但是从ConfigFileApplicationListener的supportsEventType方法来看明细它是不支持ApplicationStartingEvent。

    1.3 Listner排序并发布

    对于上述筛选出来的listener,为了确保其执行顺序则对它进行排序:

    AnnotationAwareOrderComparator.sort(allListeners);
    

    这种排序已经看到在许多地方出现过,比如初始化SpringApplication的Initializers和Listeners,所以这里不再详细说明。

    1.3.1 发布Listener

    以下是筛选了支持指定事件的Listener:

    public class SimpleApplicationEventMulticaster extends AbstractApplicationEventMulticaster {
    	@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);
    			}
    		}
    	}
    }
    

    由于executor为空,所以这里都是调用了else方法提内的invokeListener方法。
    对于listener来说,每个listener都会实现ApplicationListener或者其子接口SmartApplicationListener,所以它们都会重写onApplicationEvent方法:

    public class SimpleApplicationEventMulticaster extends AbstractApplicationEventMulticaster {
    	private void doInvokeListener(ApplicationListener listener, ApplicationEvent event) {
    		try {
    			// 最终还是调用每个支持该事件的listener中的重写了父类的onApplicationEvent方法
    			listener.onApplicationEvent(event);
    		}
    		catch (ClassCastException ex) {
    			String msg = ex.getMessage();
    			if (msg == null || matchesClassCastMessage(msg, event.getClass())) {
    				Log logger = LogFactory.getLog(getClass());
    				if (logger.isTraceEnabled()) {
    					logger.trace("Non-matching event type for listener: " + listener, ex);
    				}
    			}
    			else {
    				throw ex;
    			}
    		}
    	}
    }	
    

    1.3.2 发布Listener说明

    贯穿整个SpringBoot的启动过程,会有多次类似上面获取监听器所支持的事件进行发布,区别在于不同的初始化流程传入的需要支持的事件类型不同, 以下是EventPublishingRunListener的源码:

    public class EventPublishingRunListener implements SpringApplicationRunListener, Ordered {
    
    	@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));
    	}
    
    	......
    }
    
  • 相关阅读:
    响应式设计
    小视频-上传视频
    美多商城项目总结
    jwt 接口加密
    flask入门小方法
    flask的继承和包含
    flask中的宏
    flask的jinja2模板中过过滤器的相关小内容
    flask中的简单的前端写入
    flask的cookie和session的简单原理
  • 原文地址:https://www.cnblogs.com/Json1208/p/13352751.html
Copyright © 2020-2023  润新知