1.run启动

2020-09-28  本文已影响0人  山海树

1.调用run方法,最终会返回ConfigurableApplicationContext 对象

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

ConfigurableApplicationContext 类是一个SPI的接口,继承了ApplicationContext,Lifecycle,Closeable三个类,这里封装了配置和生命周期方法,以避免客户端显式的操作applicationContext,当前方法只能通过启动和停止代码来使用该对象。

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

接下来需要初始化一个SpringApplication对象,传入的Class对象则是启动类对象。

  public SpringApplication(ResourceLoader resourceLoader, Class<?>... primarySources) {
        this.resourceLoader = resourceLoader;//resourceLoader == null
        Assert.notNull(primarySources, "PrimarySources must not be null");
        this.primarySources = new LinkedHashSet<>(Arrays.asList(primarySources));
         //这一步将返回一个WebApplicationType枚举类,该类有三个状态NONE,SERVLET,REACTIVE
        //通过使用当前默认的类加载器,在classpath中查找是否有满足某个规则的类,如果都没加载到,则返回SERVLET
        this.webApplicationType = WebApplicationType.deduceFromClasspath();
        //ApplicationContextInitializer是spring组件spring-context组件中的一个接口,主要是spring ioc容器刷新之前的一个回调接口,用于处于自定义逻辑
       //该方法加载系统默认配置的所有的ApplicationContextInitializer
        setInitializers((Collection) getSpringFactoriesInstances(ApplicationContextInitializer.class));
       //该方法加载系统默认配置的所有的ApplicationListener
        setListeners((Collection) getSpringFactoriesInstances(ApplicationListener.class));
       //在当前堆栈中获得一个有main方法的主类
        this.mainApplicationClass = deduceMainApplicationClass();
    }

接下来使用刚构建的SpringApplication来执行run方法()

public ConfigurableApplicationContext run(String... args) {
                //计时器
        StopWatch stopWatch = new StopWatch();
               //开始计时
        stopWatch.start();
                // 声明返回的变量
        ConfigurableApplicationContext context = null;
                // SpringBootExceptionReporter通过回调方法来记录启动是的异常报告
        Collection<SpringBootExceptionReporter> exceptionReporters = new ArrayList<>();
                //java.awt.headless是J2SE的一种模式用于在缺少显示屏、键盘或者鼠标时的系统配置,很多监控工具如jconsole 需要将该值设置为true,系统变量默认为true
        configureHeadlessProperty();
                //创建并启动监听器,args是main方法中传来的参数,用于创建监听器构造函数
        SpringApplicationRunListeners listeners = getRunListeners(args);
        listeners.starting();
        try {
                        // 将main方法的入参作为配置参数保存起来,后面使用,
            ApplicationArguments applicationArguments = new DefaultApplicationArguments(args);
                        //构造容器环境
                        //1.根据之前webApplicationType 来确定要创建的环境类型
                        // 2.在创建的环境中设置配置文件、profile、监听器环境配置,
                        //3.将该环境绑定到SpringApplication中
            ConfigurableEnvironment environment = prepareEnvironment(listeners, applicationArguments);
                        //4.设置配置文件中配置的需要忽略的类
            configureIgnoreBeanInfo(environment);
                        //加载banner文件,打印banner文件
            Banner printedBanner = printBanner(environment);
                        // 根据webApplicationType 创建容器
            context = createApplicationContext();
                        // 实例化错误报告
            exceptionReporters = getSpringFactoriesInstances(SpringBootExceptionReporter.class,
                    new Class[] { ConfigurableApplicationContext.class }, context);
                        //准备容器,将环境,监听器,参数,等设置好
            prepareContext(context, environment, listeners, applicationArguments, printedBanner);
                        // 刷新容器
            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;
    }
上一篇下一篇

猜你喜欢

热点阅读