前言
上篇我们介绍了SpringApplication.run过程包含的大致内容,这篇我们细节讲下run里面的SpringApplicationRunListeners过程。
从代码我们可以看到listeners的主要使用或引用的点:
- getRunListeners
- starting
- prepareEnvironment
- prepareContext
- started
- handleRunFailure
- running
我们挨个分析,首先SpringApplicationRunListeners是干什么的,其实通过上篇大致应该能猜到,或者通过SpringApplicationRunListener接口能猜到,可以简单的理解成spring application 启动过程的监听(SpringApplicationRunListener),而SpringApplicationRunListeners则是出发这些监听的执行者。
SpringApplicationRunListener接口
首先我们看下SpringApplicationRunListener接口:
public interface SpringApplicationRunListener {
void starting();
void environmentPrepared(ConfigurableEnvironment environment);
void contextPrepared(ConfigurableApplicationContext context);
void contextLoaded(ConfigurableApplicationContext context);
void started(ConfigurableApplicationContext context);
void running(ConfigurableApplicationContext context);
void failed(ConfigurableApplicationContext context, Throwable exception);
}
可以看出listener的过程主要就分为:启动中、environment预处理、context预处理、context加载完成、启动完成、运行中、失败几个过程。
SpringApplicationRunListeners代码比较简单,这里就不贴了,主要就是组合模式的将SpringApplicationRunListener集合组合,然后循环调用,当然failed的方法而外加了一层异常捕获和日志打印。
getRunListeners 方法
回到正题,getRunListeners初始化构造SpringApplicationRunListeners对象,在方法中我们可以看到主要调用getSpringFactoriesInstances获取所有的SpringApplicationRunListener实现。(注:getSpringFactoriesInstances这个方法用到的地方比较多,会详细介绍一下。)
private SpringApplicationRunListeners getRunListeners(String[] args) {
Class<?>[] types = new Class<?>[] { SpringApplication.class, String[].class };
return new SpringApplicationRunListeners(logger, getSpringFactoriesInstances(
SpringApplicationRunListener.class, types, this, args));
}
getSpringFactoriesInstances 方法
把几个方法揉在一起看,更容易理解:
private <T> Collection<T> getSpringFactoriesInstances(Class<T> type,
Class<?>[] parameterTypes, Object... args) {
//类加载器
ClassLoader classLoader = getClassLoader();
Set<String> names = new LinkedHashSet<>(
SpringFactoriesLoader.loadFactoryNames(type, classLoader));
List<T> instances = createSpringFactoriesInstances(type, parameterTypes,
classLoader, args, names);
AnnotationAwareOrderComparator.sort(instances);
return instances;
}
public static List<String> loadFactoryNames(Class<?> factoryType, @Nullable