跳到主要内容
  1. Environment 抽象
  2. Environment 标准实现
  3. Environment 资源加载
  4. Environment 属性获取
  5. Spring Boot Environment 生命周期
  6. Spring Cloud Environment 生命周期
  7. Environment 扩展点
  8. Environment 扩展点执行顺序

版本说明:

  • Spring Boot 2.4.8
  • Spring Cloud Hoxton.SR11,对应的Spring Boot 2.3.10.RELEASE

Environment 抽象

org.springframework.core.env.Environment 环境配置

  • profile 环境
  • Property 配置信息解析

org.springframework.core.env.ConfigurableEnvironment 可配置的环境

  • profile 环境可配置
  • MutablePropertySources 可变的属性配置源
    • org.springframework.core.env.PropertySources 多个属性配置源 @PropertySources
      • org.springframework.core.env.PropertySource 属性配置源 @PropertySource

org.springframework.web.context.ConfigurableWebEnvironment 可配置的web环境(针对Servlet)

  • ServletContext Servlet上下文
  • ServletConfig Servlet配置

org.springframework.boot.web.reactive.context.ConfigurableReactiveWebEnvironment 可配置的响应式web环境

Spring Cloud中抽象

  • org.springframework.cloud.config.environment.Environment 环境配置
  • org.springframework.cloud.config.environment.PropertySource 属性配置源

Environment 资源加载

扩展知识:资源 org.springframework.core.io.Resource

  • org.springframework.boot.env.PropertySourceLoader 配置属性加载器
    • org.springframework.boot.env.PropertiesPropertySourceLoader Properties文件配置属性加载器
    • org.springframework.boot.env.YamlPropertySourceLoader Yaml配置属性加载器
  • org.springframework.cloud.bootstrap.config.PropertySourceLocator 配置属性加载器(Spring Cloud)

Environment 属性获取

  • org.springframework.core.env.PropertyResolver 配置解析器,Environment子类

    • getProperty(String key) 获取指定key的值
    • getProperty(String key, String defaultValue) 获取指定key的值,没有值的话为默认值
    • getProperty(String key, Class<T> targetType) 获取指定key的值并进行转换
    • getProperty(String key, Class<T> targetType, T defaultValue) 获取指定key的值并进行转换,没有值的话为默认值
  • org.springframework.boot.context.properties.bind.Binder 配置绑定器

    • bind(java.lang.String, org.springframework.boot.context.properties.bind.Bindable<T>) 绑定方法
    Binder binder = Binder.get(environment);
    String userName = binder.bind("user.name", String.class).orElse("-1");

Environment 标准实现

  • org.springframework.core.env.StandardEnvironment 标准环境实现

    • systemProperties 系统属性 -- System.getProperties()
    • systemEnvironment 系统环境配置 -- System.getenv()
  • org.springframework.web.context.support.StandardServletEnvironment 标准Servlet环境实现

    Servlet配置实现初始为占位实现StubPropertySource,后面初始化的时候进行替换

    • servletConfigInitParams Servlet配置参数
    • servletContextInitParams Servlet上下文参数
    • jndiProperties jndi配置(如果有的话)
  • org.springframework.boot.web.reactive.context.StandardReactiveWebEnvironment 标准响应式Web环境实现

Spring Boot Environment 生命周期

以标准Servlet环境为例,主要是prepareEnvironment阶段

  1. 创建或者返回Environment,若是配置过直接返回,没有配置的话根据类型推断出Environment 实现

    org.springframework.boot.ApplicationServletEnvironment,其为StandardServletEnvironment 子类实现

  2. 配置属性源

    • 添加或者合并defaultProperties,放在末位

    • 添加或者合并commandLineArgs,放到首位

      若是存在commandLineArgs,创建组合配置,新的为springApplicationCommandLineArgs,再添加上commandLineArgs

    • 配置profile,钩子方法,暂时未进行实现

  3. 组装属性源为调整configurationProperties配置,并将其放到首位

  4. SpringApplicationRunListener发布ApplicationEnvironmentPreparedEvent事件

    • EnvironmentPostProcessorApplicationListener 环境后置处理器,最高优先级 + 10
      • 获取并执行EnvironmentPostProcessor
        • RandomValuePropertySourceEnvironmentPostProcessor 添加random配置源,放在systemEnvironment之后或者最后
        • SystemEnvironmentPropertySourceEnvironmentPostProcessor 字符响应处理
        • SpringApplicationJsonEnvironmentPostProcessor 处理spring.application.json或者 SPRING_APPLICATION_JSON配置的json字符串,添加到Servlet配置前或者首位
        • CloudFoundryVcapEnvironmentPostProcessor 加载vcap配置源信息,放到命令行commandLineArgs之后或者放到首位
        • ConfigDataEnvironmentPostProcessor(ConfigFileApplicationListener)配置数据的加载
        • IntegrationPropertiesEnvironmentPostProcessor 加载META-INF/spring.integration.properties,将其放到末位
    • DelegatingApplicationListener 加载配置context.listener.classes的类ApplicationListenerApplicationEventMulticaster进行广播当前事件,优先级0
  5. defaultProperties配置移动到末位

  6. 绑定环境信息到SpringApplication

  7. 需要的话将Environment转换为类型推断的Environment 实现

  8. 组装属性源为调整configurationProperties配置,并将其放到首位

prepareContext应用上下文准备阶段,也可以修改Environment

  1. 执行ApplicationContextInitializer#initialize方法
    • DelegatingApplicationContextInitializer 加载context.initializer.classes配置ApplicationContextInitializer
    • ServerPortInfoApplicationContextInitializer 加载启动端口到配置local.server.port,其中server可以被替换
  2. SpringApplicationRunListener发布ApplicationContextInitializedEvent事件
    • DelegatingApplicationListener 加载配置context.listener.classes的类ApplicationListenerApplicationEventMulticaster进行广播当前事件,优先级0
  3. 加载BeanDefinition
    • BeanDefinitionLoader#load()
  4. SpringApplicationRunListener发布ApplicationPreparedEvent事件
    • DelegatingApplicationListener 加载配置context.listener.classes的类ApplicationListenerApplicationEventMulticaster进行广播当前事件,优先级0

Spring Cloud Environment 生命周期

org.springframework.cloud.bootstrap.BootstrapApplicationListener ApplicationEnvironmentPreparedEvent事件,最高优先级 + 5,也就是说在**EnvironmentPostProcessorApplicationListener类之前执行**,application(-*).yml(properties)配置文件比较靠后加载,所以下面的配置信息配置在application(-*).yml(properties)配置文件中无效,只能配置在bootstrap(-*).yml(properties)配置文件中

  1. BootstrapApplicationListener ApplicationEnvironmentPreparedEvent事件

    • 加载配置spring.cloud.bootstrap.location以及spring.cloud.bootstrap.additional-location

    • 配置源类 BootstrapImportSelectorConfiguration,加载类BootstrapImportSelector

      • 加载配置文件/META-INF/spring.factories中org.springframework.cloud.bootstrap.BootstrapConfiguration配置类
        • org.springframework.cloud.config.server.environment.EnvironmentRepositoryPropertySourceLocator 环境资源仓储属性资源加载器,配置spring.cloud.config.server.bootstrap=true加载并且需要在BootstrapConfiguration配置类中配置一个名为defaultEnvironmentRepositoryEnvironmentRepository,不然默认加载为org.springframework.cloud.config.server.config.DefaultRepositoryConfiguration
        • org.springframework.cloud.config.client.ConfigServicePropertySourceLocator 配置服务属性资源加载器,引入spring-cloud-config-client加载
      • 加载配置spring.cloud.bootstrap.sources配置的类

      加载配置文件还是ConfigDataEnvironmentPostProcessor(ConfigFileApplicationListener)这个类进行处理

      • 添加org.springframework.context.ApplicationContextInitializer bean信息
        • org.springframework.cloud.bootstrap.config.PropertySourceBootstrapConfiguration 执行PropertySourceLocator
        • org.springframework.cloud.bootstrap.encrypt.EnvironmentDecryptApplicationInitializer 解密{cipher}配置值
  2. 执行PropertySourceBootstrapConfiguration#initialize方法,执行PropertySourceLocator#locateCollection

Environment扩展点

Spring Cloud Environment 扩展点

  • 配置文件/META-INF/spring.factories中org.springframework.cloud.bootstrap.BootstrapConfiguration配置PropertySourceLocator实现类

  • systemProperties 系统属性、systemEnvironment 系统环境配置以及bootstrap(-*).yml(properties)配置文件配置spring.cloud.bootstrap.sources的值为PropertySourceLocator实现类

  • 实现EnvironmentRepository并在BootstrapConfiguration配置类配置为defaultEnvironmentRepository的Bean,在systemProperties 系统属性、systemEnvironment 系统环境配置以及bootstrap(-*).yml(properties)配置文件配置spring.cloud.config.server.bootstrap=true

    若是不以defaultEnvironmentRepository名称的Bean,默认加载为org.springframework.cloud.config.server.config.DefaultRepositoryConfiguration

    若是配置多个实现EnvironmentRepository,需要再配置一个@PrimaryCompositeEnvironmentRepository

Spring Boot Environment 扩展点

  • 实现事件(ApplicationEnvironmentPreparedEvent、ApplicationContextInitializedEvent、ApplicationPreparedEvent)监听并在配置文件/META-INF/spring.factories中org.springframework.context.ApplicationListener配置
  • 在环境配置中添加context.listener.classes配置事件(ApplicationEnvironmentPreparedEvent、ApplicationContextInitializedEvent、ApplicationPreparedEvent)监听类
  • 实现EnvironmentPostProcessor并在配置文件/META-INF/spring.factories中org.springframework.boot.env.EnvironmentPostProcessor配置
  • ConfigDataEnvironmentPostProcessor(ConfigFileApplicationListener)配置数据的加载,会先加载profile对应配置,后加载默认(default)配置
  • 实现ApplicationContextInitializer并在配置文件/META-INF/spring.factories中org.springframework.context.ApplicationContextInitializer配置
  • 在环境配置中添加context.initializer.classes配置ApplicationContextInitializer实现类

Environment 扩展点执行顺序

  1. PropertySourceLocator 执行
  2. EnvironmentRepository 执行
  3. ApplicationEnvironmentPreparedEvent 优先级在最高优先级 + 10 之前的执行
  4. EnvironmentPostProcessor 执行
  5. ApplicationEnvironmentPreparedEvent 优先级在最高优先级 + 10 之后的执行
  6. ApplicationContextInitializer 执行
  7. ApplicationContextInitializedEvent 执行
  8. ApplicationPreparedEvent 执行