美文网首页
1.run启动

1.run启动

作者: 山海树 | 来源:发表于2020-09-28 16:29 被阅读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;
        }
    

    相关文章

      网友评论

          本文标题:1.run启动

          本文链接:https://www.haomeiwen.com/subject/asbduktx.html