SpringBoot 启动流程

SpringBoot 启动流程

1. 启动类 main 方法

启动类中的 main 方法做为入口,直接使用 SpringApplication 类的静态方法调用 run()方法,传入当前main方法所在的类。

public static void main(String[] args) {
   SpringApplication.run(Sb2Application.class, args);
}

2. SpringApplication调用 run 方法

run方法里面将 传入的类包装成class 数组再次调用了另一个 静态的 run方法

public static ConfigurableApplicationContext run(Class<?> primarySource, String... args) {
  return run(new Class<?>[] { primarySource }, args);
}

另一个静态方法 new 一个 SpringApplication 的实例对象并且调用对象的 run方法,传入 main 方法所在的类,并出入args

public static ConfigurableApplicationContext run(Class<?>[] primarySources, String[] args) {
  return new SpringApplication(primarySources).run(args);
}

上面步骤最后调用方法做了两件事,
第一件是调用 SpringApplication的构造器
第二件是低啊用了对象级别的 run 方法

3. SpringApplication 默认构造方法调用

public SpringApplication(ResourceLoader resourceLoader, Class<?>... primarySources) {
//① 初始化 resourceLoader 这个默认为空
  this.resourceLoader = resourceLoader;
  Assert.notNull(primarySources, "PrimarySources must not be null");
//② 初始化 primarySource 属性,是传入近来类的class 转换成的 Set 数据集,赋给了primarySource
  this.primarySources = new LinkedHashSet<> (Arrays.asList(primarySources));
//③ 初始化 webApplicationType 字段,表明该容器跑的是哪类web 容器默认是servletw
		this.webApplicationType = WebApplicationType.deduceFromClasspath();
//④ 初始化上下文初始类的工厂类,读取默认的配置文件创建出上下文的实例放入实例工厂对象中
		setInitializers((Collection) getSpringFactoriesInstances(ApplicationContextInitializer.class));
//⑤ 初始化监听器类的工厂类,读取默认配置文件创建出所有监听器放入对应的工厂类中
		setListeners((Collection) getSpringFactoriesInstances(ApplicationListener.class));
// ⑥ 推断出当前启动容器的对象也就是入口类对应的对象
		this.mainApplicationClass = deduceMainApplicationClass();
}

4. 调用 run 方法

public ConfigurableApplicationContext run(String... args) {
// 1. 开启计时
   StopWatch stopWatch = new StopWatch();
   stopWatch.start();
// 2.声明 ConfigurableApplicationContext 对象
   ConfigurableApplicationContext context = null;
// 3.创建 一个Collection<SpringBootExceptionReporter>  对象
   Collection<SpringBootExceptionReporter> exceptionReporters = new ArrayList<>();
// 4.设置是该应用程序,即使没有检测到显示器,也允许其启动
   configureHeadlessProperty();
// 5.获取创建的SpringApplicationRunListeners 监听器,并触发启动事件
   SpringApplicationRunListeners listeners = getRunListeners(args);
   listeners.starting();
   try {
// 6.新建 ApplicationArguments对象      
      ApplicationArguments applicationArguments = new DefaultApplicationArguments(args);
// 7.新建 ConfigurableEnvironment 对象       
      ConfigurableEnvironment environment = prepareEnvironment(listeners, applicationArguments);
// 8.设置需要忽略的 bean       
      configureIgnoreBeanInfo(environment);
// 9.打印 Banner       
      Banner printedBanner = printBanner(environment);
// 10.创建ApplicationContext对象       
      context = createApplicationContext();
// 11.创建exceptionReporters对象       
      exceptionReporters = getSpringFactoriesInstances(SpringBootExceptionReporter.class, new Class[] { ConfigurableApplicationContext.class }, context);
// 13.准备 context       
      prepareContext(context, environment, listeners, applicationArguments, printedBanner);
// 14.刷新 context (重要)       
      refreshContext(context);
// 15.刷新后的方法调用       
      afterRefresh(context, applicationArguments);
// 16.停止计时       
      stopWatch.stop();
      if (this.logStartupInfo) {
         new StartupInfoLogger(this.mainApplicationClass)
             .logStarted(getApplicationLog(), stopWatch);
      }
      listeners.started(context);
      callRunners(context, applicationArguments);
   }
   catch (Throwable ex) {
      handleRunFailure
          (context, ex, exceptionReporters, listeners);
      throw new IllegalStateException(ex);
   }
   try {
      listeners.running(context);
   }
   catch (Throwable ex) {
      handleRunFailure
          (context, ex, exceptionReporters, null);
      throw new IllegalStateException(ex);
   }
   return context;
}

img

https://www.jianshu.com/p/87f101d8ec41

原文地址:https://www.cnblogs.com/vawa/p/13266898.html