美文网首页Spring源码
Spring源码0. springboot启动流程以及源码剖析目

Spring源码0. springboot启动流程以及源码剖析目

作者: ygxing | 来源:发表于2019-07-31 18:42 被阅读0次

    目录

        1. 初始化SpringApplication实例

        2. 发布启动事件ApplicationStartingEvent

        3. 封装命令行参数DefaultApplicationArguments

        4. prepareEnvironment()准备环境

        5. printBanner()打印Banner

        6. createApplicationContext()创建应用上下文

        7. SpringBootExceptionReporter异常上报

        8. prepareContext()准备应用上下文

        9. refreshContext()刷新应用上下文

        10. 启动完成, 发布ApplicationStartedEvent, ApplicationReadyEvent事件


    前言

    当我们使用springboot的时候, 我们只需要配置如下启动类, spring便可以配置所有的环境和上下文, 本文基于springboot2.1.3, 剖析spring的启动流程和原理

    @SpringBootApplication
    public class YanggxApplication {
        public static void main(String[] args) {
            //调用SpringApplication的run方法
            SpringApplication.run(YanggxApplication.class, args);
        }
    }
    

    SpringApplication运行代码

    SpringApplication整个启动流程大概分为10个重要的步骤, 将会在之后的文章中逐个步骤分析

    public class SpringApplication {
        
        //SpringApplication.run方法
        public static ConfigurableApplicationContext run(Class<?>[] primarySources,
                String[] args) {
            //步骤1. 初始化SpringApplication实例
            return new SpringApplication(primarySources).run(args);
        }
    
        /**
         * 启动Spring 应用
         * @param args YanggxApplication中main函数的参数
         */
        public ConfigurableApplicationContext run(String... args) {
            //实例化一个StopWatch实例, 监控项目运行时间
            StopWatch stopWatch = new StopWatch();
            stopWatch.start();
            //初始化Spring上下文和错误报告参数
            ConfigurableApplicationContext context = null;
            Collection<SpringBootExceptionReporter> exceptionReporters = new ArrayList<>();
            //配置headless,在没有显示器,鼠标,键盘的情况下,仍然可以调用显示,输入输出的方法
            configureHeadlessProperty();
        
            //步骤2.发布Spring启动事件
            //获取SpringApplicationRunListeners
            //listeners的监听器列表中只包含了一个EventPublishingRunListener对象
            SpringApplicationRunListeners listeners = getRunListeners(args);
        
            //调用SpringFactoriesLoader#starting方法,
            //最终调用EventPublishingRunListener#starting方法
            listeners.starting();
            
            try {
                //步骤3. 封装命令行参数DefaultApplicationArguments
                ApplicationArguments applicationArguments = new DefaultApplicationArguments(args);
                
                //步骤4. prepareEnvironment()准备环境
                ConfigurableEnvironment environment = prepareEnvironment(listeners,applicationArguments);
                configureIgnoreBeanInfo(environment);
                
                //步骤5: printBanner()打印Banner
                Banner printedBanner = printBanner(environment);
                
                //步骤6: createApplicationContext()创建应用上下文
                context = createApplicationContext();
                
                //步骤7: SpringBootExceptionReporter异常上报
                exceptionReporters = getSpringFactoriesInstances(
                        SpringBootExceptionReporter.class,
                        new Class[] { ConfigurableApplicationContext.class }, context);
                //步骤8: prepareContext()准备应用上下文
                prepareContext(context, environment, listeners, applicationArguments,printedBanner);
                
                //步骤9: refreshContext()刷新应用上下文
                refreshContext(context);
                
                //步骤10: 启动完成, 发布ApplicationStartedEvent, ApplicationReadyEvent事件
                afterRefresh(context, applicationArguments);
                stopWatch.stop();
                if (this.logStartupInfo) {
                    new StartupInfoLogger(this.mainApplicationClass).logStarted(getApplicationLog(),stopWatch);
                }
                //发布ApplicationStartedEvent
                listeners.started(context);
                callRunners(context, applicationArguments);
            }
            catch (Throwable ex) {
                handleRunFailure(context, ex, exceptionReporters, listeners);
                throw new IllegalStateException(ex);
            }
        
            try {
                //发布ApplicationReadyEvent事件
                listeners.running(context);
            }
            catch (Throwable ex) {
                handleRunFailure(context, ex, exceptionReporters, null);
                throw new IllegalStateException(ex);
            }
            return context;
        }
    }
    

    相关文章

      网友评论

        本文标题:Spring源码0. springboot启动流程以及源码剖析目

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