首页常见问题正文

SpringApplication实例的初始化和项目初始化启动

更新时间:2023-08-11 来源:黑马程序员 浏览量:

SpringApplication实例的初始化

查看SpringApplication实例对象初始化的源码信息,核心代码如下。

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 = new HashSet();
    this.isCustomEnvironment = false;
    this.resourceLoader = resourceloader;
    Assert.notNull (primarySources, "PrimarySources must not be null");
    this.primarySorces = new LinkedlashSep(Arrays.aslist(primarySources));
    this.webApplicationType = WebApplicationType.daduceFromClasspath () ;
    this.setInitializers (this.getSpringFactoriesInstances(

                                        ApplicationContextInitializer.class)) ;
    this.setListeners (this.getSpringFactoriesInstances (ApplicationIistener.class)) ;
    this.mainApplicationClass = this.deduceMainApplicationClass ();
}
从上述源码可以看出,SpringApplication的初始化过程主要包括4部分,具体说明如下。

(1) this.webApplicationType = WebApplicationType.deduceFromClasspath()

用于判断当前 webApplicationType 应用的类型。deduceFromClasspath()方法用于查看Classpath 类路径下是否存在某个特征类,从而判断当前webApplicationType类型是SERVLET应用(Spring 5之前的传统MVC应用)还是REACTIVE应用(Spring 5开始出现的WebFlux交互式应用)。

(2 ) this.setlnitializers(this.getSpringFactorieslnstances(ApplicationContextlnitializer.class))

用于设置SpringApplication 应用的初始化器。在初始化器设置过程中,会使用Spring类加载器 SpringFactoriesLoader 从 META-INF/spring.factories 类路径下的 META-INF 下的spring.factores 文件中获取所有可用的应用初始化器类ApplicationContextlnitializer。

(3) this.setListeners(this.getSpringFactoriesinstances(ApplicationListener.class))

用于设置 SpringApplication应用的监听器。监听器设置的过程与上一步初始化器设置的过程基本一样,也是使用SpringFactoriesLoader从 META-INF/spring.factories 类路径下的META-INF下的spring.factores文件中获取所有可用的监听器类ApplicationListener。

(4) this.mainApplicationClass = this.deduceMainApplicationClass()

用于推断并设置项目main()方法启动的主程序启动类。

项目的初始化启动

分析完(new SpringApplication(primarySources)).run(args)源码前一部分 SpringApplication实例对象的初始化后,查看run(args)方法执行的项目初始化启动过程,核心代码如下。

public ConfigurableApplicationContext run(String... args) {
    StopNatch stopWatch = new StopNatch();
    stopMatch.start();
    ConfigurableApplicationContext context = null;
    Collection<SpringBootExceptionReporter> exceptionReporters = new ArrayList ();
    this.configureHeadlessProperty();
    // (1) 获取SpringApplicat ion 初始化的 SpringApplicationRunListener 运行监听器井运行
    SpringApplicationRunListeners listeners = this. getRunListeners (args) ;
    listeners.starting() ;
    Collection exceptionReporters;
    try {
        ApplicationArgunents applicationArguments =
                    new DefaultApplicationArguments (args);
        //(2)项目运行环境Environment的顶配置
        ConfigurableEnvironment environment =
                        this.prepareEnvirorment(listeners, applicationArgunents) ;
        this.configureIgnoreBeanInfo (environment) ;
        Banner printedBanner = this.printBanner (environment);
        //(3)项目应用上下文Applicat ionContext 的预配置
        context = this.createApplicationContext();
        exceptionReporters =
                  this.getSpringF'actoriesInstances(SpringBootExoeptionReporter.class,
            new Class [] {ConfigurableApplicationContext.class), new Cbject[] {context}) ;
                          this.prepareContext (context, environment, listeners,
                                               applicationArguments, printedBanner) ;
        this.refreshContext(context) ;
        this.afterRefresh (context, applicationArguments);
        stopNatch.stop();
        if(this.logStartupInfo) {
            (new StartupInfoLogger(this.mainApplicationClass))
                                   .logStarted(this.getApplicationLog(), stoplatch);
        }
        //(4)由项目运行监听器启动配置好的应用上下文ApplicationContext
        listeners.started(context);
        //(5)调用应用上下文ApplicationContext中配置的程序执行器XxxRunner
        this.callRunners (context, applicationArguments) ;
    } catch (Throwable var10) {
        this.handleRunFailure (context, var10, exceptionReporters, listeners};
        throw new IllegalStateException(var10);
    }
    try {
        //(6)由项目运行监听器持续运行配置好的应用上下文ApplicationContext
        listeners")rs.running (context);
        return context;
    } catch (Throwable var9) {
    this.handleRunFailure (context, var9, exceptionReporters,
                                (SpringApplicationRunListeners) null);
    throw new IllegalStateException(var9);
    }
}

从上述源码可以看出,项目初始化启动过程大致包括以下6部分。

(1)this.getRunListeners(args)和listeners.starting()方法主要用于获取 SpringApplication实例初始化过程中初始化的SpringApplicationRunListener 监听器并运行。

(2)this.prepareEnvironment(listeners,applicationArguments)方法主要用于对项目运行环境进行预设置,同时通过 this.configurelgnoreBeanlnfo(environment)方法排除一些不需要的运行环境。

(3)this.createApplicationContext()方法及下面加粗部分代码,主要作用是对项目应用上下文ApplicationContext的预配置,包括先创建应用上下文环境ApplicationContext,接着使用之前初始化设置的context(应用上下文环境)、environment(项目运行环境)、listeners(运行监听器)、applicationArguments(项目参数)和 printedBanner(项目图标信息)进行应用上下文的组装配置,并刷新配置。

(4)listeners.started(context)方法用于使运行监听器SpringApplicationRunListener启动配置好的应用上下文 ApplicationContext。

(5)this.callRunners(context,applicationArguments)方法用于调用项自中自定义的执行器XxxRunner类,使得在项目启动完成后立即执行一些特定程序。其中,Spring Boot提供的执行器接口有ApplicationRunner 和 CommandLineRunner 两种,在使用时只需要自定义一个执行器类实现其中一个按]并重写对应的run()方法接口,Spring Boot 项目启动后即会立即执行这些特定程序。

(6) listeners.running(context)方法表示在前面一切初始化启动都没有问题的情况下,使用运行监听器SpringApplicationRunListener 持续运行配置好的应用上下文ApplicationContext,这样整个Spring Boot 项目就正式启动完成了。与此同时,经过初始化封装设置的应用上下文

ApplicationContext也处于活跃状态。

至此,关于Spring Boot执行流程中项目的初始化启动已经分析完毕。经过上面对项目启动过程中两阶段源码的详细分析,相信大家对Spring Boot 执行流程已经有了大体的认识,虽然大部分内容都较为复杂,但在学习过程中只要了解源码中部分重要内容即可。

下面我们通过一个Spring Boot 执行流程图,来让大家更清晰地知道 Spring Boot的整体执行流程和主要启动阶段,具体如所示。
Spring Boot的整体执行流程

分享到:
在线咨询 我要报名
和我们在线交谈!