美文网首页
SpringBoot2.2.6启动run方法之Environme

SpringBoot2.2.6启动run方法之Environme

作者: 噼咔丘 | 来源:发表于2020-05-25 16:57 被阅读0次

    前言

    此系列是针对springboot的启动,旨在于和大家一起来看看springboot启动的过程中到底做了一些什么事。文中有不清楚或错误的地方
    欢迎留言指正。

    源码解读进度

    首先我们的源码阅读进度

    public ConfigurableApplicationContext run(String... args) {
        // 用于记录启动时间
        StopWatch stopWatch = new StopWatch();
        stopWatch.start();
        // 声明Spring上下文
        ConfigurableApplicationContext context = null;
        // 声明启动错误回掉
        Collection<SpringBootExceptionReporter> exceptionReporters = new ArrayList<>();
        // 设置jdk系统属性java.awt.headless,默认情况为true即开启
        configureHeadlessProperty();
        // 装饰者模式创建启动监听器(EventPublishingRunListener实例)
        SpringApplicationRunListeners listeners = getRunListeners(args);
        // 触发ApplicationStartingEvent事件,包括转换器的初始化
        listeners.starting();
        try {
            // 参数封装,也就是在命令行下启动应用带的参数
            ApplicationArguments applicationArguments = new DefaultApplicationArguments(args);
            // 准备环境:1、加载外部化配置的资源到environment;2、触发ApplicationEnvironmentPreparedEvent事件
            ConfigurableEnvironment environment = prepareEnvironment(listeners, applicationArguments);
            configureIgnoreBeanInfo(environment);
            Banner printedBanner = printBanner(environment);
            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;
    }
    

    先从加载方法说起

    private ConfigurableEnvironment prepareEnvironment(SpringApplicationRunListeners listeners,
                ApplicationArguments applicationArguments) {
        // 1. 根据webApplicationType类型,创建对应的Environment, 
        // 本文基于web环境分析,加载的是StandardServletEnvironment
        ConfigurableEnvironment environment = getOrCreateEnvironment();
        // 2. 配置Environment,一、设置ConversionService,二、配置数据源、包括命令行参数,三、配置profiles
        configureEnvironment(environment, applicationArguments.getSourceArgs());
        // 3. 配置configurationProperties
        ConfigurationPropertySources.attach(environment);
        // 4. 发送ApplicationEnvironmentPreparedEvent事件,接收事件后环境变量的处理。下面详细分析
        listeners.environmentPrepared(environment);
        bindToSpringApplication(environment);
        if (!this.isCustomEnvironment) {
            environment = new EnvironmentConverter(getClassLoader()).convertEnvironmentIfNecessary(environment,
                    deduceEnvironmentClass());
        }
        ConfigurationPropertySources.attach(environment);
        return environment;
    }
    

    listeners.environmentPrepared(environment)做了那些事情

    • ConfigFileApplicationListener接收到ApplicationEnvironmentPreparedEvent事件
    private void onApplicationEnvironmentPreparedEvent(ApplicationEnvironmentPreparedEvent event) {
        // 加载后置处理器
        List<EnvironmentPostProcessor> postProcessors = loadPostProcessors();
        // 同时自己也是一个后置处理器
        postProcessors.add(this);
        // 排序
        AnnotationAwareOrderComparator.sort(postProcessors);
        // 分别调用后置处理器方法
        for (EnvironmentPostProcessor postProcessor : postProcessors) {
            postProcessor.postProcessEnvironment(event.getEnvironment(), event.getSpringApplication());
        }
    }
    

    后置处理器以及排序如下:

    1. SystemEnvironmentPropertySourceEnvironmentPostProcessor 系统变量处理
    2. SpringApplicationJsonEnvironmentPostProcessor json格式环境变量处理
    3. CloudFoundryVcapEnvironmentPostProcessor spring-cloud环境用到
    4. ConfigFileApplicationListener 初始化配置文件
    5. DebugAgentEnvironmentPostProcessor

    相关文章

      网友评论

          本文标题:SpringBoot2.2.6启动run方法之Environme

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