码迷,mamicode.com
首页 > 移动开发 > 详细

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

时间:2019-10-13 13:23:25      阅读:130      评论:0      收藏:0      [点我收藏+]

标签:framework   runtime   ble   目的   path   gap   obj   cat   dha   

	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()

标签:framework   runtime   ble   目的   path   gap   obj   cat   dha   

原文地址:https://www.cnblogs.com/itivy/p/11665758.html

(0)
(0)
   
举报
评论 一句话评论(0
登录后才能评论!
© 2014 mamicode.com 版权所有  联系我们:gaon5@hotmail.com
迷上了代码!