public SpringApplication(ResourceLoader resourceLoader, Class<?>... primarySources) { this.resourceLoader = resourceLoader; Assert.notNull(primarySources, "PrimarySources must not be null"); this.primarySources = new LinkedHashSet<>(Arrays.asList(primarySources))
//(1).根据classpath中的存在的类推断应用类型
this.webApplicationType = WebApplicationType.deduceFromClasspath();
//(2).获取ApplicationContextInitializer,并设置到Initializers中
setInitializers((Collection) getSpringFactoriesInstances( ApplicationContextInitializer.class));
//(3).获取ApplicationContextInitializer,并设置到Initializers中
setListeners((Collection) getSpringFactoriesInstances(ApplicationListener.class));
//(4).推断主类
this.mainApplicationClass = deduceMainApplicationClass();
}
调用链路为:
at org.springframework.boot.SpringApplication.<init>(SpringApplication.java:265) at org.springframework.boot.SpringApplication.<init>(SpringApplication.java:249) at org.springframework.boot.SpringApplication.run(SpringApplication.java:1260) at org.springframework.boot.SpringApplication.run(SpringApplication.java:1248) at com.ivy.demo.DemoApplication.main(DemoApplication.java:16)
(1).推断应用类型
主要逻辑根据classPath中存在的类,判断应用类型
this.webApplicationType = WebApplicationType.deduceFromClasspath();
static WebApplicationType deduceFromClasspath() {
//springframework.web.reactive.DispatcherHandler类
//但是不存在org.springframework.web.servlet.DispatcherServlet和org.glassfish.jersey.servlet.ServletContainer类
//返回WebApplicationType.REACTIVE类型 if (ClassUtils.isPresent(WEBFLUX_INDICATOR_CLASS, null) && !ClassUtils.isPresent(WEBMVC_INDICATOR_CLASS, null) && !ClassUtils.isPresent(JERSEY_INDICATOR_CLASS, null)) { return WebApplicationType.REACTIVE; }
//不存在javax.servlet.Servlet和org.springframework.web.context.ConfigurableWebApplicationContext
//返回WebApplicationType.NONE
for (String className : SERVLET_INDICATOR_CLASSES)
{
if (!ClassUtils.isPresent(className, null))
{
return WebApplicationType.NONE;
}
}
return WebApplicationType.SERVLET;
}
2.setInitializers
主要逻辑是通过classLoader加载所有classPath中的META-INF/spring.factories文件,将加载的key(接口或者子类)-value(接口的实现类)缓存到map中,并返回指定接口的实现类结合
这里获取的是配置的ApplicationContextInitializer的所有配置的实现类
setInitializers((Collection) getSpringFactoriesInstances( ApplicationContextInitializer.class));
private <T> Collection<T> getSpringFactoriesInstances(Class<T> type) { return getSpringFactoriesInstances(type, new Class<?>[] {}); }
private <T> Collection<T> getSpringFactoriesInstances(Class<T> type, Class<?>[] parameterTypes, Object... args) { ClassLoader classLoader = getClassLoader();
// (1).获取classPath所有META-INF/spring.factories中配置的key为ApplicationContextInitializer的接口
Set<String> names = new LinkedHashSet<>(
SpringFactoriesLoader.loadFactoryNames(type, classLoader));
// (2).初始化所有配置ApplicationContextInitializer的接口的实现类
List<T> instances = createSpringFactoriesInstances(type, parameterTypes, classLoader, args, names);
AnnotationAwareOrderComparator.sort(instances);
return instances;
}
public static List<String> loadFactoryNames(Class<?> factoryClass, @Nullable ClassLoader classLoader) {
//(1).获取class类型名称 String factoryClassName = factoryClass.getName();
//(2).通过classLoader加载所有的META-INF/spring.factories中配置的属性值,并取得需要factoryClassName类型的
//factoryClassName对应接口的实现类 return loadSpringFactories(classLoader).getOrDefault(factoryClassName, Collections.emptyList()); }
private static Map<String, List<String>> loadSpringFactories(@Nullable ClassLoader classLoader) { MultiValueMap<String, String> result = cache.get(classLoader);
//(1).判断当前classLoader是否已经加载过,加载过直接返回
if (result != null) { return result; } try {
//(2).获取classPath中所有META-INF/spring.factories,可能需要递归到父classLoader Enumeration<URL> urls = (classLoader != null ? classLoader.getResources(FACTORIES_RESOURCE_LOCATION) : ClassLoader.getSystemResources(FACTORIES_RESOURCE_LOCATION)); result = new LinkedMultiValueMap<>();
//(3).读取所有的url指定文件,保存到以文件中key为key的map(集中同一类型的实现类) while (urls.hasMoreElements()) { URL url = urls.nextElement(); UrlResource resource = new UrlResource(url); Properties properties = PropertiesLoaderUtils.loadProperties(resource); for (Map.Entry<?, ?> entry : properties.entrySet()) { String factoryClassName = ((String) entry.getKey()).trim(); for (String factoryName : StringUtils.commaDelimitedListToStringArray((String) entry.getValue())) { result.add(factoryClassName, factoryName.trim()); } } }
//(4).保存到缓存 cache.put(classLoader, result); return result; } catch (IOException ex) { throw new IllegalArgumentException("Unable to load factories from location [" + FACTORIES_RESOURCE_LOCATION + "]", ex); } }
(3).setListeners
主要逻辑和(2)类似,只是这里获取的是配置的ApplicationListener的所有配置的实现类
setListeners((Collection) getSpringFactoriesInstances(ApplicationListener.class));
(4).deduceMainApplicationClass
根据调用链接,推断主类(方法中包含‘main’字符串)
this.mainApplicationClass = deduceMainApplicationClass();
private Class<?> deduceMainApplicationClass() { try { StackTraceElement[] stackTrace = new RuntimeException().getStackTrace(); for (StackTraceElement stackTraceElement : stackTrace) { if ("main".equals(stackTraceElement.getMethodName())) { return Class.forName(stackTraceElement.getClassName()); } } } catch (ClassNotFoundException ex) { // Swallow and continue } return null; }