美文网首页Spring
Spring Boot启动-构造容器环境

Spring Boot启动-构造容器环境

作者: 王勇1024 | 来源:发表于2019-02-24 14:22 被阅读7次

    容器的运行环境包含了应用配置和环境相关信息,后面所有关于配置和环境的操作都基于此类。构建容器环境实现代码如下:

        /**
         * 构建容器环境
         * @param listeners  监听器
         * @param applicationArguments  命令行参数
         * @return 构建的环境对象
         */
        private ConfigurableEnvironment prepareEnvironment(
                SpringApplicationRunListeners listeners,
                ApplicationArguments applicationArguments) {
            // 第一步:创建Environment实例
            ConfigurableEnvironment environment = getOrCreateEnvironment();
            // 第二步:配置Environment
            configureEnvironment(environment, applicationArguments.getSourceArgs());
            // 第三步:监听回调
            listeners.environmentPrepared(environment);
            // 第四步:绑定到SpringApplication
            bindToSpringApplication(environment);
            //这一步是非SpringMVC项目的处理,暂时忽略
            if (!this.isCustomEnvironment) {
                environment = new EnvironmentConverter(getClassLoader())
                        .convertEnvironmentIfNecessary(environment, deduceEnvironmentClass());
            }
            // 绑定ConfigurationPropertySourcesPropertySource到ConfigurableEnvironment中,name为configurationProperties,实例是SpringConfigurationPropertySources,属性实际是ConfigurableEnvironment中的MutablePropertySources
            ConfigurationPropertySources.attach(environment);
            return environment;
        }
    

    从代码中可以看到,构建容器环境主要包含四个步骤:

    1. 创建Environment实例
    2. 配置Environment
    3. 监听回调
    4. 绑定到SpringApplication

    第一步:创建Environment实例

    根据Web应用类型不同,Spring Boot提供了三种容器环境,如果是SERVLET应用,则使用StandardServletEnvironment,如果是REACTIVE应用,则使用StandardReactiveWebEnvironment,其他情况都使用StandardEnvironment。
    StandardServletEnvironment和StandardReactiveWebEnvironment都继承自StandardEnvironment,不同之处在于,StandardServletEnvironment增加了加载和解析web.xml配置的逻辑。
    具体代码如下:

        private ConfigurableEnvironment getOrCreateEnvironment() {
            if (this.environment != null) {
                return this.environment;
            }
            switch (this.webApplicationType) {
            case SERVLET:
                return new StandardServletEnvironment();
            case REACTIVE:
                return new StandardReactiveWebEnvironment();
            default:
                return new StandardEnvironment();
            }
        }
    

    第二步:配置Environment

    Environment是当前应用运行环境的公开接口,主要包括应用程序运行环境的两个关键方面:配置文件(profiles)和属性。Environment继承自接口PropertyResolver,而PropertyResolver提供了属性访问的相关方法。
    配置Environment包含两部分:

    1. 配置Properties
      // Environment继承关系
      在构建StandardEnvironment对象时,会调用System.getProperty()和System.getEnv()方法,这两个方法分别用于加载系统配置和系统环境变量。详情参考:系统变量之System.getEnv()和System.getProperty()
      如果需要将命令行参数存入Environment配置中,则会解析命令行参数为KV形式,并保存到Environment配置中。
    2. 配置Profiles
        protected void configureProfiles(ConfigurableEnvironment environment, String[] args) {
            environment.getActiveProfiles(); // ensure they are initialized
            // But these ones should go first (last wins in a property key clash)
            Set<String> profiles = new LinkedHashSet<>(this.additionalProfiles);
            profiles.addAll(Arrays.asList(environment.getActiveProfiles()));
            environment.setActiveProfiles(StringUtils.toStringArray(profiles));
        }
    

    第三步:监听回调

    在这个过程中,会遍历所有在spring.factories文件中配置的SpringApplicationRunListeners实例,并调用其environmentPrepared方法。
    配置文件的加载就是在监听器的回调方法中完成的。

    第四步:绑定到SpringApplication

    在这个过程中,会将刚才构建好的Environment对象绑定到当前的SpringApplication中。

    相关文章

      网友评论

        本文标题:Spring Boot启动-构造容器环境

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