1、SpringApplication 对象实例化
SpringApplication 文件
public static ConfigurableApplicationContext run(Object[] sources, String[] args) {
// 传递的source其实就是类Bootstrap
return new SpringApplication(sources).run(args);
// 实例化一个SpringApplication对象执行run方法
}
实例化的时候又会执行initialize 方法
private void initialize(Object[] sources) {
// 这个source依旧是上文说的Bootstrap.class 类
if (sources != null && sources.length > 0) {
this.sources.addAll(Arrays.asList(sources));
// 添加到source资源列表里面去
}
this.webEnvironment = deduceWebEnvironment();
// 设置其是否为web环境
setInitializers((Collection) getSpringFactoriesInstances(
ApplicationContextInitializer.class));
setListeners((Collection) getSpringFactoriesInstances(ApplicationListener.class));
// 拆分为两步,一步是getSpringFactoriesInstances,再者就是set操作
// set操作很简单,就是设置当前对象的初始化对象以及监听器
this.mainApplicationClass = deduceMainApplicationClass();
// 通过堆栈信息,推断 main方法的类对象为当前的主程序类
}
private static final String[] WEB_ENVIRONMENT_CLASSES = { "javax.servlet.Servlet",
"org.springframework.web.context.ConfigurableWebApplicationContext" };
private boolean deduceWebEnvironment() {
for (String className : WEB_ENVIRONMENT_CLASSES) {
// 遍历包含上述两个类名称的数组
if (!ClassUtils.isPresent(className, null)) {
// 一旦发现不存在该类,就立即返回 deduce 推断不是web环境
return false;
}
}
// 必须同时包含两个类,才推断出为web环境
return true;
}
getSpringFactoriesInstances 方法操作
private <T> Collection<? extends T> getSpringFactoriesInstances(Class<T> type,
Class<?>[] parameterTypes, Object... args) {
// 传递的type就是上面说的ApplicationContextInitializer.class以及ApplicationListener.class类
// 类型以及参数目前都没有具体指
ClassLoader classLoader = Thread.currentThread().getContextClassLoader();
// Use names and ensure unique to protect against duplicates
Set<String> names = new LinkedHashSet<String>(
SpringFactoriesLoader.loadFactoryNames(type, classLoader));
// 通过SpringFactoriesLoader 获取对应的名称,具体详情可以看下面的代码块
// 这点需要重点关注下!!!
// 结果就是返回一个set集合
List<T> instances = createSpringFactoriesInstances(type, parameterTypes,
classLoader, args, names);
// 看样子就是创建一个实例的集合
AnnotationAwareOrderComparator.sort(instances);
// 然后通过AnnotationAwareOrderComparator 的排序规则跪实例集合进行排序
// 排序就是看是否存在Order或者Priority注解,然后取得注解的值,排在集合前面
return instances;
}
private <T> List<T> createSpringFactoriesInstances(Class<T> type,
Class<?>[] parameterTypes, ClassLoader classLoader, Object[] args,
Set<String> names) {
List<T> instances = new ArrayList<T>(names.size());
for (String name : names) {
// 遍历上面取到的name 集合
try {
Class<?> instanceClass = ClassUtils.forName(name, classLoader);
// 取到这个类名称的类
Assert.is