springboot启动逻辑分析一-------new SpringApplication()
Posted itivy
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了springboot启动逻辑分析一-------new SpringApplication()相关的知识,希望对你有一定的参考价值。
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(); }
(1).推断应用类型
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; }
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;
}
}
//否则返回WebApplicationType.SERVLET
return WebApplicationType.SERVLET;
}
(2)设置Initializers
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(); // Use names and ensure unique to protect against duplicates Set<String> names = new LinkedHashSet<>( SpringFactoriesLoader.loadFactoryNames(type, classLoader)); List<T> instances = createSpringFactoriesInstances(type, parameterTypes, classLoader, args, names); AnnotationAwareOrderComparator.sort(instances); return instances; }
setInitializers((Collection) getSpringFactoriesInstances( //(2).初始ApplicationContextInitializer
ApplicationContextInitializer.class));
setListeners((Collection) getSpringFactoriesInstances(ApplicationListener.class)); //(3).确定ApplicationListener
this.mainApplicationClass = deduceMainApplicationClass(); //(4).确定mainApplicationClass
(1).推断应用类型,依据判断classPath是否存在
this.webApplicationType = WebApplicationType.deduceFromClasspath();
(2).确定ApplicationContextInitializer,目的待定,重点是读取classpath下的META-INF/spring.factories,并缓存
setInitializers((Collection) getSpringFactoriesInstances(
ApplicationContextInitializer.class));
(3).确定ApplicationListener,目的待定,重点是读取classpath下的META-INF/spring.factories,并缓存
setListeners((Collection) getSpringFactoriesInstances(ApplicationListener.class));
(4).确定mainApplicationClass,重点new RuntimeException().getStackTrace()可以获取堆栈
this.mainApplicationClass = deduceMainApplicationClass();
以上是关于springboot启动逻辑分析一-------new SpringApplication()的主要内容,如果未能解决你的问题,请参考以下文章