springboot启动逻辑分析一-------new SpringApplication()

宝剑锋从磨砺出,梅花香自苦寒来。这篇文章主要讲述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(); }

【springboot启动逻辑分析一-------new SpringApplication()】(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();

    推荐阅读