Spring Boot 启动流程源码分析

Posted bluesky1

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了Spring Boot 启动流程源码分析相关的知识,希望对你有一定的参考价值。

学习过springboot的都知道,在Springboot的main入口函数中调用SpringApplication.run(DemoApplication.class,args)函数便可以启用SpringBoot应用程序,跟踪一下SpringApplication源码可以发现,最终还是调用了SpringApplication的动态run函数。

下面以SpringBoot2.0.3.RELEASE为例简单分析一下运行过程。

SpringApplicatiton部分源码:

1 public static ConfigurableApplicationContext run(Class<?>[] primarySources,
2       String[] args) 
3   //创建springapplication对象,调用函数run(args)
4    return new SpringApplication(primarySources).run(args);
5 

上面的源码可以发现还是先创建SpringApplication实例,再调用run方法

第一步 分析 SpringApplication构造函数

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:判断web环境
  this.webApplicationType = deduceWebApplicationType();

  //2:加载classpath下META-INF/spring.factories中配置的ApplicationContextInitializer
  setInitializers((Collection) getSpringFactoriesInstances(
  ApplicationContextInitializer.class));
  //3:加载classpath下META-INF/spring.factories中配置的ApplicationListener

  setListeners((Collection) getSpringFactoriesInstances(ApplicationListener.class));
  //4:推断main方法所在的类
  this.mainApplicationClass = deduceMainApplicationClass();

具体逻辑分析:

deduceWebApplicationType(),  SpringApplication构造函数中首先初始化应用类型,根据加载相关类路径判断应用类型,具体逻辑如下:

1   private static final String REACTIVE_WEB_ENVIRONMENT_CLASS = "org.springframework."
2 + "web.reactive.DispatcherHandler";
3
4   private static final String MVC_WEB_ENVIRONMENT_CLASS = "org.springframework."
5 + "web.servlet.DispatcherServlet";
6
7   private static final String[] WEB_ENVIRONMENT_CLASSES = "javax.servlet.Servlet",
8 "org.springframework.web.context.ConfigurableWebApplicationContext" ;
9
10
11
12 private WebApplicationType deduceWebApplicationType()
13   //当类路径中存在REACTIVE_WEB_ENVIRONMENT_CLASS并且不存在MVC_WEB_ENVIRONMENT_CLASS时
14 if (ClassUtils.isPresent(REACTIVE_WEB_ENVIRONMENT_CLASS, null)
15 && !ClassUtils.isPresent(MVC_WEB_ENVIRONMENT_CLASS, null))
16 return WebApplicationType.REACTIVE;
17
18   //当加载的类路径中不包含WEB_ENVIRONMENT_CLASSES中定义的任何一个类时,返回标准应用()
19 for (String className : WEB_ENVIRONMENT_CLASSES)
20 if (!ClassUtils.isPresent(className, null)) 22 return WebApplicationType.NONE;
23
24
25   //加载的类路径中包含了WEB_ENVIRONMENT_CLASSES中定义的所有类型则判断为servlet的web应用
26 return WebApplicationType.SERVLET;
27

以上是关于Spring Boot 启动流程源码分析的主要内容,如果未能解决你的问题,请参考以下文章

头秃系列,二十三张图带你从源码分析Spring Boot 启动流程~

spring boot 源码解析 启动流程

Dubbo启动源码解析一

Spring Boot -- 启动流程分析一

[Spring Boot] 1. Spring Boot启动过程源码分析

[Spring Boot] 1. Spring Boot启动过程源码分析