Spring Environment 简介
- Environment 抽象
- Environment 标准实现
- Environment 资源加载
- Environment 属性获取
- Spring Boot Environment 生命周期
- Spring Cloud Environment 生命周期
- Environment 扩展点
- 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>)
绑定方法
1
2Binder 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阶段
创建或者返回Environment,若是配置过直接返回,没有配置的话根据类型推断出Environment 实现
org.springframework.boot.ApplicationServletEnvironment
,其为StandardServletEnvironment
子类实现配置属性源
添加或者合并
defaultProperties
,放在末位添加或者合并
commandLineArgs
,放到首位若是存在
commandLineArgs
,创建组合配置,新的为springApplicationCommandLineArgs
,再添加上commandLineArgs
配置
profile
,钩子方法,暂时未进行实现
组装属性源为调整
configurationProperties
配置,并将其放到首位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
,将其放到末位
- RandomValuePropertySourceEnvironmentPostProcessor 添加
- 获取并执行
DelegatingApplicationListener
加载配置context.listener.classes
的类ApplicationListener
并ApplicationEventMulticaster
进行广播当前事件,优先级0
将
defaultProperties
配置移动到末位绑定环境信息到SpringApplication
需要的话将Environment转换为类型推断的Environment 实现
组装属性源为调整
configurationProperties
配置,并将其放到首位
prepareContext
应用上下文准备阶段,也可以修改Environment
- 执行
ApplicationContextInitializer#initialize
方法DelegatingApplicationContextInitializer
加载context.initializer.classes
配置ApplicationContextInitializerServerPortInfoApplicationContextInitializer
加载启动端口到配置local.server.port
,其中server可以被替换
SpringApplicationRunListener
发布ApplicationContextInitializedEvent
事件DelegatingApplicationListener
加载配置context.listener.classes
的类ApplicationListener
并ApplicationEventMulticaster
进行广播当前事件,优先级0
- 加载
BeanDefinition
BeanDefinitionLoader#load()
SpringApplicationRunListener
发布ApplicationPreparedEvent
事件DelegatingApplicationListener
加载配置context.listener.classes
的类ApplicationListener
并ApplicationEventMulticaster
进行广播当前事件,优先级0
Spring Cloud Environment 生命周期
org.springframework.cloud.bootstrap.BootstrapApplicationListener
ApplicationEnvironmentPreparedEvent事件,最高优先级 + 5,也就是说在**EnvironmentPostProcessorApplicationListener
类之前执行**,application(-*).yml(properties)
配置文件比较靠后加载,所以下面的配置信息配置在application(-*).yml(properties)
配置文件中无效,只能配置在bootstrap(-*).yml(properties)
配置文件中
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
配置类中配置一个名为defaultEnvironmentRepository
的EnvironmentRepository
,不然默认加载为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}
配置值
- 加载配置文件/META-INF/spring.factories中
执行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
,需要再配置一个@Primary
的CompositeEnvironmentRepository
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 扩展点执行顺序
PropertySourceLocator
执行EnvironmentRepository
执行ApplicationEnvironmentPreparedEvent
优先级在最高优先级 + 10 之前的执行EnvironmentPostProcessor
执行ApplicationEnvironmentPreparedEvent
优先级在最高优先级 + 10 之后的执行ApplicationContextInitializer
执行ApplicationContextInitializedEvent
执行ApplicationPreparedEvent
执行