宝剑锋从磨砺出,梅花香自苦寒来。这篇文章主要讲述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();
推荐阅读
- 分析Android APK-砸壳-Fdex2
- APP登录Token认证过程
- ST5222: Advanced Topics in Applied Statistics
- Android实现apk插件方式换肤
- 非常实用的冷门APP合集,小众但却逆天好用!
- Android中Activity中访问数据库操作记录
- Appium解决native+webview混合型APP(公众号小程序)切换webview后元素无法定位问题
- Appium行为事件处理
- Android OkHttp, 一行代码 OkHttp提升请求稳定性