springboot学习(一)框架整体启动流程

springboot启动:在Application中通过SpringApplication.run()方法,并向其中传入主类以及args来完成启动

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

那么springboot是怎么通过run这行代码来启动springboot呢?

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

通过源码可以看到,它一共分为两步,首先实例化一个SpringApplication对象,其次调用它的run方法。

1.框架初始化(new SpringApplication(primarySources))

  public SpringApplication(ResourceLoader resourceLoader, Class... primarySources) {
    this.sources = new LinkedHashSet();
    this.bannerMode = Mode.CONSOLE;
    this.logStartupInfo = true;
    this.addCommandLineProperties = true;
    this.headless = true;
    this.registerShutdownHook = true;
    this.additionalProfiles = new HashSet();
    this.resourceLoader = resourceLoader;
    Assert.notNull(primarySources, "PrimarySources must not be null");
    this.primarySources = new LinkedHashSet(Arrays.asList(primarySources));
    this.webApplicationType = this.deduceWebApplicationType();
    this.setInitializers(this.getSpringFactoriesInstances(ApplicationContextInitializer.class));
    this.setListeners(this.getSpringFactoriesInstances(ApplicationListener.class));
    this.mainApplicationClass = this.deduceMainApplicationClass();
  }
  • 配置资源加载器
  • 配置primarySources
  • 应用环境检测
  • 配置系统初始化器
  • 配置应用监听器
  • 配置main方法所在类

2.框架启动(调用run方法)

  public ConfigurableApplicationContext run(String... args) {
    StopWatch stopWatch = new StopWatch();
    stopWatch.start();
    ConfigurableApplicationContext context = null;
    Collection<SpringBootExceptionReporter> exceptionReporters = new ArrayList();
    this.configureHeadlessProperty();
    SpringApplicationRunListeners listeners = this.getRunListeners(args);
    listeners.starting();

    Collection exceptionReporters;
    try {
      ApplicationArguments applicationArguments = new DefaultApplicationArguments(args);
      ConfigurableEnvironment environment = this.prepareEnvironment(listeners, applicationArguments);
      this.configureIgnoreBeanInfo(environment);
      Banner printedBanner = this.printBanner(environment);
      context = this.createApplicationContext();
      exceptionReporters = this.getSpringFactoriesInstances(SpringBootExceptionReporter.class, new Class[]{ConfigurableApplicationContext.class}, context);
      this.prepareContext(context, environment, listeners, applicationArguments, printedBanner);
      this.refreshContext(context);
      this.afterRefresh(context, applicationArguments);
      stopWatch.stop();
      if (this.logStartupInfo) {
        (new StartupInfoLogger(this.mainApplicationClass)).logStarted(this.getApplicationLog(), stopWatch);
      }

      listeners.started(context);
      this.callRunners(context, applicationArguments);
    } catch (Throwable var10) {
      this.handleRunFailure(context, var10, exceptionReporters, listeners);
      throw new IllegalStateException(var10);
    }

    try {
      listeners.running(context);
      return context;
    } catch (Throwable var9) {
      this.handleRunFailure(context, var9, exceptionReporters, (SpringApplicationRunListeners)null);
      throw new IllegalStateException(var9);
    }
  }
  • 计时器开始计时
  • Headless模式赋值
  • 获取监听器
  • 发送ApplicationStartingEvent
  • 构造容器环境
  • 发送ApplicationEnvironmentPreparedEvent
  • 设置需要忽略的Bean
  • 打印banner
  • 创建上下文对象
  • 实例化SpringBootExceptionReporter.class(失败分析器),用来支持报告关于启动的错误
  • 关联springboot组件与应用上下文对象
  • 发送ApplicationContextInitializedEvent
  • 加载source到context
  • 发送ApplicationPreparedEvent
  • 刷新上下文
  • 计时器停止计时
  • 发送ApplicationStartedEvent
  • 调用框架启动扩展类
  • 发送ApplicationReadyEvent

3.框架自动化装备(属于框架启动部分)

  • 收集配置文件中的配置工厂类
  • 加载组件工厂
  • 注册组件内定义的bean

由此可见虽然我们启动springboot只用了一行代码,但其背后的原理和步骤还是比较多的

猜你喜欢

转载自blog.csdn.net/qq_33302985/article/details/106095257
今日推荐