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

调用链路为:

    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;
    }
原文地址:https://www.cnblogs.com/itivy/p/11665758.html