• 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

  • 相关阅读:
    联表查询更新
    SQLServer 中多行数据合并成一行数据(一个字段)
    换行和回车的区别
    SQL语句中使用回车换行符
    g2o使用总结
    求导总结
    ubuntu14.04 升级gcc
    如何入门SLAM
    imu和canmera标定
    使用velodyne16线激光雷达跑loam-velodyne------包括激光雷达和imu的标定
  • 原文地址:https://www.cnblogs.com/vawa/p/13266898.html
Copyright © 2020-2023  润新知