前言
上一篇SpringBoot源码分析之-启动流程分析二(run方法)简单分析了的run流程
这一篇主要分析一下监听器 SpringApplicationRunListener
观察者模式
class SpringApplicationRunListeners {
//监听器集合
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();
}
}
//其他方法差不多就是处理同的事件
...
}
public interface SpringApplicationRunListener {
default void starting() {}
default void environmentPrepared(ConfigurableEnvironment environment) {}
default void contextPrepared(ConfigurableApplicationContext context) {}
default void contextLoaded(ConfigurableApplicationContext context) {}
default void started(ConfigurableApplicationContext context) {}
default void running(ConfigurableApplicationContext context) {}
default void failed(ConfigurableApplicationContext context, Throwable exception) {}
}
//---EventPublishingRunListener 方法对应的事件
starting: ApplicationStartingEvent
environmentPrepared: ApplicationEnvironmentPreparedEvent
contextPrepared: ApplicationContextInitializedEvent
contextLoaded: ApplicationPreparedEvent
started: ApplicationStartedEvent
running: ApplicationReadyEvent
failed: ApplicationFailedEvent
这个比较好看出是用了观察者模式
SpringApplicationRunListeners 中维护了SpringApplicationRunListener集合,
ApplicationEvent广播SpringApplicationRunListener处理相应的事件
run方法中出现的地方
//获取监听器
SpringApplicationRunListeners listeners = getRunListeners(args);
//广播 ApplicationStartingEvent
listeners.starting();
//准备环境
ConfigurableEnvironment environment = prepareEnvironment(listeners, applicationArguments);
//准备上下文
prepareContext(context, environment, listeners, applicationArguments, printedBanner);
//广播容器启动成功
listeners.started(context);
//广播容器运行
listeners.running(context);
//还有一个catch中的失败广播
handleRunFailure(context, ex, exceptionReporters, listeners);
1.获取监听器
private SpringApplicationRunListeners getRunListeners(String[] args) {
Class<?>[] types = new Class<?>[] { SpringApplication.class, String[].class };
return new SpringApplicationRunListeners(logger,
getSpringFactoriesInstances(SpringApplicationRunListener.class, types, this, args));
}
getSpringFactoriesInstances方法之前分析过就是从类路径下的所有META-INF/spring.factories中去获取对应的实现类 ,这里是SpringApplicationRunListener对应实现类实例
这里目前一个实现类org.springframework.boot.context.event.EventPublishingRunListener
2. starting()
void starting() {
for (SpringApplicationRunListener listener : this.listeners) {
listener.starting();
}
}
@Override
public void starting() {
this.initialMulticaster.multicastEvent(new ApplicationStartingEvent(this.application, this.args));
}
//SimpleApplicationEventMulticaster
@Override
public void multicastEvent(ApplicationEvent event) {
multicastEvent(event, resolveDefaultEventType(event));
}
@Override
public void multicastEvent(final ApplicationEvent event, @Nullable ResolvableType eventType) {
ResolvableType type = (eventType != null ? eventType : resolveDefaultEventType(event));
//现在是null
Executor executor = getTaskExecutor();
//getApplicationListeners根据是否支持事件过滤SpringApplication设置的监听器
for (ApplicationListener<?> listener : getApplicationListeners(event, type)) {
if (executor != null) {
executor.execute(() -> invokeListener(listener, event));
}
else {
invokeListener(listener, event);
}
}
}
protected void invokeListener(ApplicationListener<?> listener, ApplicationEvent event) {
//==null
ErrorHandler errorHandler = getErrorHandler();
if (errorHandler != null) {
try {
doInvokeListener(listener, event);
}
catch (Throwable err) {
errorHandler.handleError(err);
}
}
else {
doInvokeListener(listener, event);
}
}
private void doInvokeListener(ApplicationListener listener, ApplicationEvent event) {
try {
//对应的监听器执行方法
listener.onApplicationEvent(event);
}
......
}
listener.onApplicationEvent(event);就是对应监听器处理事件的方法
好了到此SpringApplicationRunListener处理事件大致流程分析清楚了.其他细节有兴趣可以看下.
下一篇准备分析 prepareEnvironment环境准备.
getApplicationListeners() 筛选出支持该事件的监听器监听器
//public abstract class AbstractApplicationEventMulticaster
// implements ApplicationEventMulticaster, BeanClassLoaderAware, BeanFactoryAware {
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);
}
}
.... //下面是有bean情况下的逻辑, 现在还没到容器初始化
protected boolean supportsEvent(
ApplicationListener<?> listener, ResolvableType eventType, @Nullable Class<?> sourceType) {
GenericApplicationListener smartListener = (listener instanceof GenericApplicationListener ?
(GenericApplicationListener) listener : new GenericApplicationListenerAdapter(listener));
return (smartListener.supportsEventType(eventType) && smartListener.supportsSourceType(sourceType));
}
这里有个适配器模式,还是比较好看出的
GenericApplicationListener 和 GenericApplicationListenerAdapter
如果监听器没有实现GenericApplicationListener 就创建一个GenericApplicationListenerAdapter适配器
主要supportsEventType 和 supportsSourceType两个方法确认监听器是否符合事件
//GenericApplicationListener接口
boolean supportsEventType(ResolvableType eventType);
/**
* Determine whether this listener actually supports the given source type.
* <p>The default implementation always returns {@code true}.
* @param sourceType the source type, or {@code null} if no source
*/
default boolean supportsSourceType(@Nullable Class<?> sourceType) {
return true;
}
//-----下面是GenericApplicationListenerAdapter类
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;
this.declaredEventType = resolveDeclaredEventType(this.delegate);
}
@Override
@SuppressWarnings("unchecked")
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));
}
}
@Override
public boolean supportsEventType(Class<? extends ApplicationEvent> eventType) {
return supportsEventType(ResolvableType.forClass(eventType));
}
根据是否支持事件类型和源来过滤出监听器
举个例子:LoggingApplicationListener
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) {
return isAssignableFrom(resolvableType.getRawClass(), EVENT_TYPES);
}
@Override
public boolean supportsSourceType(Class<?> sourceType) {
return isAssignableFrom(sourceType, SOURCE_TYPES);
}
}
可以看到LoggingApplicationListener 支持的类型EVENT_TYPES 和 源类型SOURCE_TYPES
所以根据事件类型和源过滤了获取了4个类
(第一篇构造SpringApplication中获取的监听器中过滤)
0 = {CloudFoundryVcapEnvironmentPostProcessor@1725}
1 = {ConfigFileApplicationListener@1726}
2 = {AnsiOutputApplicationListener@1727}
3 = {LoggingApplicationListener@1728}
4 = {ClasspathLoggingApplicationListener@1729}
5 = {BackgroundPreinitializer@1730}
6 = {DelegatingApplicationListener@1731}
7 = {ParentContextCloserApplicationListener@1732}
8 = {ClearCachesApplicationListener@1733}
9 = {FileEncodingApplicationListener@1734}
10 = {LiquibaseServiceLocatorApplicationListener@1735}
//---
LoggingApplicationListener
BackgroundPreinitializer
DelegatingApplicationListener
LiquibaseServiceLocatorApplicationListener
**listener.onApplicationEvent(event);**监听器执行自己的方法了
这里就 LoggingApplicationListener 和 BackgroundPreinitializer 有对ApplicationStartingEvent事件类型的处理
LoggingApplicationListener 设置了日志系统 这里默认是Logback
Map<String, String> systems = new LinkedHashMap<>();
systems.put("ch.qos.logback.core.Appender", "org.springframework.boot.logging.logback.LogbackLoggingSystem");
systems.put("org.apache.logging.log4j.core.impl.Log4jContextFactory",
"org.springframework.boot.logging.log4j2.Log4J2LoggingSystem");
systems.put("java.util.logging.LogManager", "org.springframework.boot.logging.java.JavaLoggingSystem");
SYSTEMS = Collections.unmodifiableMap(systems);
BackgroundPreinitializer 起了一个线程执行以下操作 一些工具的初始化
ApplicationReadyEvent 和 ApplicationFailedEvent 也就是后续的这两个事件会等他执行完
public void onApplicationEvent(SpringApplicationEvent event) {
if (!Boolean.getBoolean(IGNORE_BACKGROUNDPREINITIALIZER_PROPERTY_NAME)
&& event instanceof ApplicationStartingEvent && multipleProcessors()
&& preinitializationStarted.compareAndSet(false, true)) {
performPreinitialization();
}
if ((event instanceof ApplicationReadyEvent || event instanceof ApplicationFailedEvent)
&& preinitializationStarted.get()) {
try {
preinitializationComplete.await();
}
catch (InterruptedException ex) {
Thread.currentThread().interrupt();
}
}
}
// performPreinitialization()
public void run() {
runSafely(new ConversionServiceInitializer());
runSafely(new ValidationInitializer());
runSafely(new MessageConverterInitializer());
runSafely(new JacksonInitializer());
runSafely(new CharsetInitializer());
preinitializationComplete.countDown();
}