SpringBoot run方法

    public ConfigurableApplicationContext run(String... args) {
        StopWatch stopWatch = new StopWatch();
        stopWatch.start();
        ConfigurableApplicationContext context = null;
        Collection exceptionReporters = new ArrayList();
        //设置系统属性『java.awt.headless』,为true则启用headless模式支持
        this.configureHeadlessProperty();
/*通过SpringFactoriesLoader检索META-INF/spring.factories,
 找到声明的所有SpringApplicationRunListener的实现类并将其实例化,
 之后逐个调用其started()方法,广播SpringBoot要开始执行了
*/
        SpringApplicationRunListeners listeners = this.getRunListeners(args);
        //发布应用开始启动事件
        listeners.starting();

        Collection exceptionReporters;
        try {
            //初始化参数
            ApplicationArguments applicationArguments = new DefaultApplicationArguments(args);
/*
创建并配置当前SpringBoot应用将要使用的Environment
(包括配置要使用的PropertySource以及Profile)
并遍历调用所有的SpringApplicationRunListener的environmentPrepared()方法,
 广播Environment准备完毕。
*/
            ConfigurableEnvironment environment = this.prepareEnvironment(listeners, applicationArguments);
            this.configureIgnoreBeanInfo(environment);
            //打印banner
            Banner printedBanner = this.printBanner(environment);
            //创建应用上下文
            context = this.createApplicationContext();
//通过*SpringFactoriesLoader*检索*META-INF/spring.factories*,获取并实例化异常分析器
            exceptionReporters = this.getSpringFactoriesInstances(SpringBootExceptionReporter.class, new Class[]{ConfigurableApplicationContext.class}, context);
            /*
为ApplicationContext加载environment,
之后逐个执行ApplicationContextInitializer的initialize()方法来进一步封装ApplicationContext,
并调用所有的SpringApplicationRunListener的contextPrepared()方法【EventPublishingRunListener只提供了一个空的contextPrepared()方法】,
之后初始化IoC容器,并调用SpringApplicationRunListener的contextLoaded()方法,广播ApplicationContext的IoC加载完成,
这里就包括通过@EnableAutoConfiguration导入的各种自动配置类。
            */
            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);
          /*
          遍历所有注册的ApplicationRunner和CommandLineRunner,并执行其run()方法。
          我们可以实现自己的ApplicationRunner或CommandLineRunner,来对SpringBoot的启动过程进行扩展。
          */
            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);
        }
    }

总结下步骤为:

  1. 配置属性
  2. 获取监听器,发布应用开始启动事件
  3. 初始化输入参数
  4. 配置环境,输出banner
  5. 创建上下文
  6. 预处理上下文
  7. 刷新上下文
  8. 再刷新上下文
  9. 发布应用已经启动事件
  10. 发布应用启动完成事件

而启动Tomcat就是在第7步中“刷新上下文”;Tomcat的启动主要是初始化2个核心组件,连接器(Connector)和容器(Container),一个Tomcat实例就是一个Server,一个Server包含多个Service,也就是多个应用程序,每个Service包含多个连接器(Connetor)和一个容器(Container),而容器下又有多个子容器,按照父子关系分别为:Engine,Host,Context,Wrapper,其中除了Engine外,其余的容器都是可以有多个。

你可能感兴趣的:(SpringBoot run方法)