Spring boot 启动原理加载配置文件prepareEnvironment(二)

  • 本文详细讲解SpringBoot(2.0.6) 在启动的时候配置文件的加载核心方法prepareEnvironment
public ConfigurableApplicationContext run(String... args) {
        StopWatch stopWatch = new StopWatch();
        stopWatch.start();
        ConfigurableApplicationContext context = null;
        Collection exceptionReporters = new ArrayList<>();
        configureHeadlessProperty();
        SpringApplicationRunListeners listeners = getRunListeners(args);
        listeners.starting();
        try {
            ApplicationArguments applicationArguments = new DefaultApplicationArguments(
                    args);
            // 本文核心讲解
            ConfigurableEnvironment environment = prepareEnvironment(listeners,
                    applicationArguments);
            configureIgnoreBeanInfo(environment);
            .....................
}

private ConfigurableEnvironment prepareEnvironment(
            SpringApplicationRunListeners listeners,
            ApplicationArguments applicationArguments) {
        // Create and configure the environment
        // 创建并且准备环境(根据应用环境 加载系统配置(JVM JDK 系统参数))
        ConfigurableEnvironment environment = getOrCreateEnvironment();
        // 加载当前默认配置文件,profiles.active,args  等信息加载
        configureEnvironment(environment, applicationArguments.getSourceArgs());
        // 触发 ApplicationEnvironmentPreparedEvent 事件,同时会触发多中监听器
        // 同时触发ConfigFileApplicationListener 加载spring配置文件
        listeners.environmentPrepared(environment);
        //将环境environment绑定到SpringApplication
        bindToSpringApplication(environment);
        if (!this.isCustomEnvironment) {
            // 类型转换
            environment = new EnvironmentConverter(getClassLoader())
                    .convertEnvironmentIfNecessary(environment, deduceEnvironmentClass());
        }
        ConfigurationPropertySources.attach(environment);
        return environment;
}


// 
/**
* 创建并且准备环境(根据应用环境 加载系统配置(JVM JDK 系统参数))
* 根据当前应用类型创建相应的Environment
* 初始化一些系统参数
**/
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();
    }
}
  • 接下来我们分析一下StandardServletEnvironment (StandardReactiveWebEnvironment 继承StandardServletEnvironment ) 所以重点分析这一部分

  • 先看一下这个类的继承关系


    StandardServletEnvironment.png
  • PropertyResolver : 属性解析器能够解析${field} 替换@Value值

  • Environment: 环境类可以根据不同的环境得到不同的值(用于切换环境的对象)

  • ConfigurablePropertyResolver :这个接口扩展除了将一个属性值转换为另一个类型的功能,以及规定了占位符以什么符号进行解析()

  • ConfigurableEnvironment 提供了修改以及添加Profiles ,以及获取系统属性的接口

  • AbstractEnvironment: ConfigurableEnvironment的基类

  • StandardEnvironment: 对AbstractEnvironment抽象类的实现

  • StandardServletEnvironment : 实现了StandardEnvironment 自定义加载资源的方法(标准针对spring Servlet web 提供环境使用) 增加(servletContextInitParams/servletConfigInitParams/jndiProperties三个属性源)

//配置环境
protected void configureEnvironment(ConfigurableEnvironment environment,
            String[] args) {
        // 将args 的参数绑定到PropertySources(MutablePropertySources)
        configurePropertySources(environment, args);
        // 配置环境(会加载System.Property属性,以及系统参数)
        configureProfiles(environment, args);
    }
  • 这个属于系统参数


    environmentParam.png

    systemEnvironment.png
  • -> 所以在此定义的系统参数的环境优先级高于配置文件中定义的环境配置
// 启动监听器
public void environmentPrepared(ConfigurableEnvironment environment) {
    for (SpringApplicationRunListener listener : this.listeners) {
        istener.environmentPrepared(environment);
    }
}

// 触发ApplicationEnvironmentPreparedEvent 事件
@Override
public void environmentPrepared(ConfigurableEnvironment environment) {
    this.initialMulticaster.multicastEvent(new ApplicationEnvironmentPreparedEvent(
            this.application, this.args, environment));
}
// 下班开溜....

你可能感兴趣的:(Spring boot 启动原理加载配置文件prepareEnvironment(二))