Spring Environment 简介
- Environment 抽象
- Environment 标准实现
- Environment 资源加载
- Environment 属性获取
- Spring Boot Environment 生命周期
- Spring Cloud Environment 生命周期
- Environment 扩展点
- Environment 扩展点执行顺序
版本说明:
Spring Boot 2.4.8Spring 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多个属性配置源@PropertySourcesorg.springframework.core.env.PropertySource属性配置源@PropertySource
org.springframework.web.context.ConfigurableWebEnvironment 可配置的web环境(针对Servlet)
ServletContextServlet上下文ServletConfigServlet配置
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.PropertiesPropertySourceLoaderProperties文件配置属性加载器org.springframework.boot.env.YamlPropertySourceLoaderYaml配置属性加载器
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,后面初始化的时候进行替换servletConfigInitParamsServlet配置参数servletContextInitParamsServlet上下文参数jndiPropertiesjndi配置(如果有的话)
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
- 加载
BeanDefinitionBeanDefinitionLoader#load()
SpringApplicationRunListener发布ApplicationPreparedEvent事件DelegatingApplicationListener加载配置context.listener.classes的类ApplicationListener并ApplicationEventMulticaster进行广播当前事件,优先级0
Spring Cloud Environment 生命周期
org.springframework.cloud.bootstrap.BootstrapApplicationListenerApplicationEnvironmentPreparedEvent事件,最高优先级 + 5,也就是说在**EnvironmentPostProcessorApplicationListener类之前执行**,application(-*).yml(properties)配置文件比较靠后加载,所以下面的配置信息配置在application(-*).yml(properties)配置文件中无效,只能配置在bootstrap(-*).yml(properties)配置文件中
BootstrapApplicationListenerApplicationEnvironmentPreparedEvent事件加载配置
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.DefaultRepositoryConfigurationorg.springframework.cloud.config.client.ConfigServicePropertySourceLocator配置服务属性资源加载器,引入spring-cloud-config-client加载
- 加载配置
spring.cloud.bootstrap.sources配置的类
加载配置文件还是ConfigDataEnvironmentPostProcessor(ConfigFileApplicationListener)这个类进行处理
- 添加
org.springframework.context.ApplicationContextInitializerbean信息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执行