SpringBoot学习(六)——SpringBoot项目的启动流程

183 阅读2分钟

这是我参与8月更文挑战的第15天,活动详情查看:8月更文挑战

我们已经整体的了解SpringBoot的项目结构和配置信息,今天就跟随SpringBoot观察整个启动流程都会经历些什么。

SpringBoot启动流程

1. main方法

main方法作为Java程序的启动入口,SpringBoot项目当然也是如此,SpringBoot项目启动时会首先找到并执行启动类下的main方法。

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

2. SpringApplication.run()

进入到main方法后,会执行性SpringApplication类的静态run方法,并将当前启动类作为参数传入进来。

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

由源码信息中可以看到:

  1. run方法的返回类型是ConfigurableApplicationContext类型
  2. 方法内部会对SpringApplication类进行初始化
  3. 初始化完成后调用类对象的run方法并返回结果

3. 初始化SpringApplication

调用SpringApplication类的构造方法进行初始化,创建SpringApplication类对象并对属性进行赋值。

public SpringApplication(Class<?>... primarySources) {
    this((ResourceLoader)null, primarySources);
}

public SpringApplication(ResourceLoader resourceLoader, Class<?>... primarySources) {
    this.sources = new LinkedHashSet();
    this.bannerMode = Mode.CONSOLE;
    this.logStartupInfo = true;
    this.addCommandLineProperties = true;
    this.addConversionService = true;
    this.headless = true;
    this.registerShutdownHook = true;
    this.additionalProfiles = Collections.emptySet();
    this.isCustomEnvironment = false;
    this.lazyInitialization = false;
    this.applicationContextFactory = ApplicationContextFactory.DEFAULT;
    this.applicationStartup = ApplicationStartup.DEFAULT;
    this.resourceLoader = resourceLoader;
    Assert.notNull(primarySources, "PrimarySources must not be null");
    this.primarySources = new LinkedHashSet(Arrays.asList(primarySources));
    this.webApplicationType = WebApplicationType.deduceFromClasspath();
    this.bootstrapRegistryInitializers =   this.getBootstrapRegistryInitializersFromSpringFactories();
   this.setInitializers(this.getSpringFactoriesInstances(ApplicationContextInitializer.class));
    this.setListeners(this.getSpringFactoriesInstances(ApplicationListener.class));
    this.mainApplicationClass = this.deduceMainApplicationClass();
}

4. SpringApplication对象的run()

调用SpringApplication对象的run()方法后,会在此方法中进行大量的配置,如run方法的返回对象ConfigurableApplicationContext就是在方法中创建、配置并最终返回结果。

public ConfigurableApplicationContext run(String... args) {
    StopWatch stopWatch = new StopWatch();
    stopWatch.start();
    DefaultBootstrapContext bootstrapContext = this.createBootstrapContext();
    ConfigurableApplicationContext context = null;
    this.configureHeadlessProperty();
    SpringApplicationRunListeners listeners = this.getRunListeners(args);
    listeners.starting(bootstrapContext, this.mainApplicationClass);

    try {
        ApplicationArguments applicationArguments = new DefaultApplicationArguments(args);
        ConfigurableEnvironment environment = this.prepareEnvironment(listeners, bootstrapContext, applicationArguments);
        this.configureIgnoreBeanInfo(environment);
        Banner printedBanner = this.printBanner(environment);
        context = this.createApplicationContext();
        context.setApplicationStartup(this.applicationStartup);
        this.prepareContext(bootstrapContext, 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, listeners);
        throw new IllegalStateException(var10);
    }
    
    try {
        listeners.running(context);
        return context;
    } catch (Throwable var9) {
        this.handleRunFailure(context, var9, (SpringApplicationRunListeners)null);
        throw new IllegalStateException(var9);
    }
}

从run方法的源码中可以分析得到,核心步骤有:

  • ①SpringApplicationRunListeners监听器创建
  • ②ConfigurableEnvironment配置环境信息创建
  • ③ConfigurableApplicationContext配置应用上下文创建 最后,在run方法中,配置应用上下文加载了环境信息和自动配置获取的所有bean定义后并返回最终的上下文对象,完成SpringBoot的整个启动过程。

具体run方法中的配置实现,天晚了,容我们下回继续学习。