• SpringBoot 启动配置原理


    几个重要的事件回调机制

    • ApplicationContextInitializer
    • SpringApplicationRunListener
    • ApplicationRunner
    • CommandLineRunner

    启动流程:

    1. 创建SpringApplication对象
      /**
       * 在springboot 2以前:
       * 调用initialize(source);
       * 在springboot 2以后,跳过了initialize()方法,直接调用run()方法
       */
      
      private void initialize(Object[] source){
          // 保存主配置类
          if(sources != null && source.length > 0){
              this.sources.addAll(Arrays.asList(sources));
          }
          // 判断当前是否是一个web应用
          this.webEnvironment = deduceWebEnvironment();
          // 从类路径下找到META-INF/spring.factories配置的所有ApplicationContextInitializer;然后保存起来
          setInitializes((Collection) getSpringFactoriesInstances(ApplicationContextInitializer.class));
          // 从类路径下找到META-INF/spring.factories配置的所有ApplicationListener;然后保存起来
         setListeners((Collection) getSpringFactoriesInstances(ApplicationListener.class));
          // 从多个配置类中找到有main方法的主配置类
          this.mainApplicationClass = deduceMainApplicationClass();
      }
    2. 运行run方法
      public ConfigurableApplicationContext run(String... args) {
              StopWatch stopWatch = new StopWatch();
              stopWatch.start();
              ConfigurableApplicationContext context = null;
              Collection<SpringBootExceptionReporter> exceptionReporters = new ArrayList<>();
              configureHeadlessProperty();
              
              // 获取SpringApplicationRunListener;从类路径下META-INF/spring.factories找到
              SpringApplicationRunListeners listeners = getRunListeners(args);
              // 回调所有的SpringApplicationRunListener.starting()方法
              listeners.starting();
              try {
                  // 封装命令行参数
                  ApplicationArguments applicationArguments = new DefaultApplicationArguments(args);
                  // 准备环境
                  ConfigurableEnvironment environment = prepareEnvironment(listeners, applicationArguments);
                  // 创建环境完成后回调SpringApplicationRunListener.environmentPrepared();表示环境准备完成
                  configureIgnoreBeanInfo(environment);
                  Banner printedBanner = printBanner(environment);
                  
                  // 创建ApplicationContext;决定创建web的ioc还是普通的ioc
                  context = createApplicationContext();
                  exceptionReporters = getSpringFactoriesInstances(SpringBootExceptionReporter.class,
                          new Class[] { ConfigurableApplicationContext.class }, context);
                  // 准备上下文环境;将environment保存到ioc中
                  // applyInitializers();回调之前保存的所有的SpringApplicationRunListener的initializers方法
                  
                  prepareContext(context, environment, listeners, applicationArguments, printedBanner);
                  // 回调所有的SpringApplicationRunListener的contextPrepared();
                  // 刷新容器;ioc容器初始化完成
                  refreshContext(context);
                  afterRefresh(context, applicationArguments);
                  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;
          }
  • 相关阅读:
    触摸屏调试【转】
    Android电容屏(二):驱动调试分析【转】
    linux输入子系统简述【转】
    Linux与Android 多点触摸协议【转】
    中断下半部tasklet【转】
    【转】轻量级文本编辑器,Notepad最佳替代品:Notepad++--不错
    【转】Android开发中adb启动失败adb连接异常的解决办法 offline
    【转】Java删除文件夹和文件
    【转】图说Android的8年演变史
    【转】基于 Android NDK 的学习之旅-----数据传输(引用数据类型)
  • 原文地址:https://www.cnblogs.com/luo-jian/p/12919111.html
Copyright © 2020-2023  润新知