(一)基础知识学习
参见Spring Cloud 配置客户端技术基础
(二)客户单端配置
主要涉及以下知识:
-
Bootstrap 配置文件
-
调整 Bootstrap 配置文件路径
-
覆盖远程配置文件属性
-
自定义 Bootstrap 配置
-
自定义 Bootstrap 配置属性源
1、Bootstrap 配置文件
注意事项一:
加载 Bootstrap 配置文件的监听器为:BootstrapApplicationListener
注意事项二:
String configName = environment.resolvePlaceholders("${spring.cloud.bootstrap.name:bootstrap}");
这段代码的意思是,若未配置
spring.cloud.bootstrap.name
属性,则读取
bootstrap.properties
或
bootstrap.yml
为Bootstrap 配置文件;若配置
spring.cloud.bootstrap.name=test
,则读取
test.properties
或
test.yml
为Bootstrap 配置文件。
注意事三:
#application.properties
#通过调整 spring.cloud.bootstrap.enabled = false,尝试关闭 bootstrap 上下文
#实际测试结果,没有效果
spring.cloud.bootstrap.enabled = false
原因解析:BootstrapApplicationListener 加载实际早于 ConfigFileApplicationListener(加载 application.yml 的监听器):
-
ConfigFileApplicationListener 的 Ordered.HIGHEST_PRECEDENCE +10(第十一位加载)
-
BootstrapApplicationListener 的 Ordered.HIGHEST_PRECEDENCE + 5(第六位加载)
要想
spring.cloud.bootstrap.enabled = false
生效,解决办法之一,就是在JVM的启动参数里设置
--spring.cloud.bootstrap.enabled = false
(这里的启动优先级比这两个更高)
注意事项四:
JVM启动参数的加载逻辑:
SpringApplication.configurePropertySources()
2、调整 Bootstrap 配置文件路径
通过前面可知,BootstrapApplicationListener 加载实际早于 ConfigFileApplicationListener(加载 application.yml 的监听器),所以想在application.yml中调整 Bootstrap 配置文件路径是无法实现的,仍然需要在JVM的启动参数里设置,设置项为
--spring.cloud.bootstrap.location = config
。调整 Bootstrap 配置文件路径之后,配置文件的加载顺序是什么,这里用一个Demo展示:
在不同的配置文件中设置 application 的名字:
application.yml
spring.application.name = spring-cloud-application
bootstrap.yml
spring.application.name = spring-cloud-bootstrap
spring-cloud.yml
spring.application.name = spring-cloud
config/spring-cloud.yml
spring.application.name = spring-cloud-config
设置JVM启动参数:
//设置 bootstrap 配置文件名为 spring-cloud
--spring.cloud.bootstrap.name = spring-cloud
//设置 Bootstrap 配置文件路径classpath:/config
--spring.cloud.bootstrap.location = config
加载效果:
applicationConfig: [classpath:/application.yml] : {
spring.application.name = spring-cloud-application
}
......
applicationConfig: [classpath:config/spring-cloud.yml] : {
spring.application.name = spring-cloud-application
}
applicationConfig: [classpath:/spring-cloud.yml] : {
spring.application.name = spring-cloud-application
}
备注:spring.application.name 最终读取的是 application.yml 中配置的项,而读取文件的顺序是:
先读 application.yml:不用说,Spring Boot上下文肯定会读到
再读:config/spring-cloud.yml:也不用说,JVM参数设置的bootstrap 配置文件名和路径
最后读spring-cloud.yml:这里就比较奇怪了,为什么还读 resources 路径下的spring-cloud.yml??
3、覆盖远程配置文件属性
默认情况,Spring Cloud 是容许覆盖的:
spring.cloud.config.allowOverride=true
。可以通过JVM启动参数,调整该属性为false(PS:但是这在本地无法生效,本地依然可以覆盖!!!这个仅适用于远程配置,远程无法再覆盖属性):
--spring.cloud.config.allowOverride=false
4、自定义 Bootstrap 配置
(1)创建
META-INF/spring.factories
文件,类似于Spring Boot 自定义 Starter;
(2)自定义Bootstrap 配置Configuration
package org.pc.bootstrap;
import org.springframework.context.ApplicationContextInitializer;
import org.springframework.context.ConfigurableApplicationContext;
import org.springframework.context.annotation.Configuration;
import org.springframework.core.env.ConfigurableEnvironment;
import org.springframework.core.env.MapPropertySource;
import org.springframework.core.env.MutablePropertySources;
import org.springframework.core.env.PropertySource;
import java.util.HashMap;
import java.util.Map;
@Configuration
public class MyConfiguration implements ApplicationContextInitializer {
@Override
public void initialize(ConfigurableApplicationContext applicationContext) {
ConfigurableEnvironment environment = applicationContext.getEnvironment();
MutablePropertySources propertySources = environment.getPropertySources();
PropertySource propertySource = createPropertySource();
propertySources.addFirst(propertySource);
}
private PropertySource createPropertySource() {
Map<String, Object> source = new HashMap<>();
source.put("name", "咸鱼");
PropertySource propertySource = new MapPropertySource("my-property-source", source);
return propertySource;
}
}
(2)配置
META-INF/spring.factories
文件,关联 Key
org.springframework.cloud.bootstrap.BootstrapConfiguration
org.springframework.cloud.bootstrap.BootstrapConfiguration=\
org.pc.bootstrap.MyConfiguration
通过以上步骤,就可以将自定义的变量放到Bootstrap 上下文中,可以通过
http://localhost:8081/actuator/env
查看新增的属性:
{
"name": "my-property-source",
"properties": {
"name": {
"value": "咸鱼"
}
}
}
5、自定义 Bootstrap 配置属性源
(1)自定义实现 PropertySourceLocator 接口
package org.pc.bootstrap;
import org.springframework.cloud.bootstrap.config.PropertySourceLocator;
import org.springframework.core.env.*;
import java.util.HashMap;
import java.util.Map;
public class MyPropertySourceLocator implements PropertySourceLocator {
@Override
public PropertySource<?> locate(Environment environment) {
if (environment instanceof ConfigurableEnvironment){
ConfigurableEnvironment configurableEnvironment = ConfigurableEnvironment.class.cast(environment);
MutablePropertySources propertySources = configurableEnvironment.getPropertySources();
propertySources.addFirst(createPropertySource());
}
return null;
}
private PropertySource createPropertySource() {
Map<String, Object> source = new HashMap<>();
source.put("nickName", "咸鱼昵称");
PropertySource propertySource = new MapPropertySource("my-property-source-1", source);
return propertySource;
}
}
(2)配置
META-INF/spring.factories
文件,关联 Key
org.springframework.cloud.bootstrap.BootstrapConfiguration
org.springframework.cloud.bootstrap.BootstrapConfiguration=\
org.pc.bootstrap.MyPropertySourceLocator
通过以上步骤,就可以将自定义的变量放到Bootstrap 上下文中,可以通过
http://localhost:8081/actuator/env
查看新增的属性:
{
"name": "my-property-source-1",
"properties": {
"nickName": {
"value": "咸鱼昵称"
}
}
}
(三)客户端和服务端联合配置
参见三、Spring cloud之服务器配置和客户端配置