1. 概述
Spring Cloud Config 是 Spring Cloud 全家桶的核心组件之一。它通过集中式服务管理应用配置数据,实现配置与微服务部署的解耦。Spring Cloud Config 不仅内置属性仓库,还支持 Git、Consul、Eureka 等开源项目集成。
本文将深入探讨在 Spring Cloud Config 中覆盖远程属性值的多种方案,分析 Spring 2.4 版本引入的限制,以及 3.0 版本带来的变化。所有示例基于 Spring Boot 3.2.2。
2. 创建 Spring Config Server
2.1. 创建配置文件
application.properties
中定义的配置会共享给所有客户端应用。我们也可以为特定应用或 Profile 定义专属配置。
在 src/main/resources/config
目录下创建 baeldung.properties
文件(假设客户端应用名为 baeldung
)。
2.2. 添加属性
在 baeldung.properties
中添加以下属性(后续将在客户端应用中使用):
hello=Hello Jane Doe!
welcome=Welcome Jane Doe!
在 src/main/resources/config/application.properties
中添加共享属性:
shared-property=This property is shared accross all client applications
2.3. Spring Boot Config Server 应用
创建配置服务端应用,需添加 spring-cloud-config-server
依赖:
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-config-server</artifactId>
</dependency>
主类添加 @EnableConfigServer
注解:
@SpringBootApplication
@EnableConfigServer
public class ConfigServer {
public static void main(String[] args) {
SpringApplication.run(ConfigServer.class, args);
}
}
在 application.properties
中配置端口和配置存储路径:
server.port=8081
spring.cloud.config.server.native.searchLocations=classpath:/config
启动服务端(激活 native profile 使用文件系统作为配置仓库):
mvn spring-boot:run -Dspring-boot.run.profiles=native
验证共享属性是否可访问:
$ curl localhost:8081/unknownclient/default
{
"name": "unknownclient",
"profiles": [
"default"
],
"label": null,
"version": null,
"state": null,
"propertySources": [
{
"name": "classpath:/config/application.properties",
"source": {
"shared-property": "This property is shared accross all client applications"
}
}
]
}
验证应用专属属性:
$ curl localhost:8081/baeldung/default
{
"name": "baeldung",
"profiles": [
"default"
],
"label": null,
"version": null,
"state": null,
"propertySources": [
{
"name": "classpath:/config/baeldung.properties",
"source": {
"hello": "Hello Jane Doe!",
"welcome": "Welcome Jane Doe!"
}
},
{
"name": "classpath:/config/application.properties",
"source": {
"shared-property": "This property is shared accross all client applications"
}
}
]
}
⚠️ 未禁用
spring.cloud.config.server.accept-empty
(默认 true),即使应用不存在(如unknownclient
),也会返回共享属性。
3. 客户端应用
3.1. 项目设置与依赖
添加 spring-cloud-starter-config
和 spring-boot-starter-web
依赖:
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-starter-config</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-web</artifactId>
</dependency>
3.2. 创建客户端应用
创建客户端主类:
@SpringBootApplication
public class Client {
public static void main(String[] args) {
SpringApplication.run(Client.class, args);
}
}
3.3. 获取配置
在 application.properties
中配置 Config Server 地址和应用名:
spring.cloud.config.name=baeldung
spring.config.import=optional:configserver:http://localhost:8081
3.4. 添加简单控制器
创建控制器展示配置属性:
@RestController
public class HelloController {
@Value("${hello}")
private String hello;
@Value("${welcome}")
private String welcome;
@Value("${shared-property}")
private String shared;
@GetMapping("hello")
public String hello() {
return this.hello;
}
@GetMapping("welcome")
public String welcome() {
return this.welcome;
}
@GetMapping("shared")
public String shared() {
return this.shared;
}
}
验证配置加载:
$ curl http://localhost:8080/hello
Hello Jane Doe!
$ curl http://localhost:8080/welcome
Welcome Jane Doe!
$ curl http://localhost:8080/shared
This property is shared accross all client applications
4. 在服务端覆盖属性
通过修改服务端配置可覆盖特定应用的属性。在服务端的 application.properties
中添加:
spring.cloud.config.server.overrides.hello=Hello Jane Doe – application.properties!
验证覆盖效果:
$ curl http://localhost:8080/hello
Hello Jane Doe - application.properties!
✅ 也可在共享配置文件
config/application.properties
中定义覆盖属性,优先级高于服务端主配置文件。
5. 在客户端覆盖属性
Spring Boot 2.4+ 后,无法直接通过客户端的 application.properties
覆盖远程属性。
5.1. 使用 Spring Profiles
本地 Profile 配置的属性优先级高于服务端应用配置。创建 application-development.properties
:
hello=Hello local property!
激活 development profile 启动客户端:
mvn spring-boot:run -Drun.profiles=development
验证覆盖:
$ curl http://localhost:8080/hello
Hello local property!
5.2. 使用占位符
通过占位符实现默认值覆盖。修改服务端 config/baeldung.properties
:
hello=${app.hello:Hello Jane Doe!}
在客户端 application.properties
中添加:
app.hello=Hello, overriden local property!
验证效果:
$ curl http://localhost:8080/hello
Hello, overriden local property!
⚠️ 若同时在 Profile 配置中定义
hello
,Profile 配置优先级更高。
6. 传统配置方式
6.1. 加载外部配置
Spring Boot 2.4 前通过 bootstrap 机制管理外部配置。添加依赖:
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-starter-bootstrap</artifactId>
</dependency>
创建 bootstrap.properties
:
spring.cloud.config.name=baeldung
spring.cloud.config.uri=http://localhost:8081
在 application.properties
中启用传统模式:
spring.config.use-legacy-processing=true
6.2. 启用覆盖能力
在服务端 baeldung.properties
中添加:
spring.cloud.config.overrideNone=true
✅ 此配置使外部属性不再优先于应用 JAR 内部定义的属性。
6.3. 覆盖服务端属性
在客户端 application.properties
中覆盖属性:
hello=localproperty
验证覆盖:
$ curl http://localhost:8080/hello
localproperty
6.4. 传统配置的废弃
❌ Spring Boot 3.0+ 已移除传统配置支持,建议使用前述现代方案。
7. 总结
本文探讨了在 Spring Cloud Config 中覆盖远程属性值的多种方式:
- ✅ 服务端覆盖:通过
spring.cloud.config.server.overrides
全局覆盖 - ✅ 客户端覆盖:
- 使用 Spring Profiles(优先级最高)
- 使用占位符提供默认值
- ⚠️ 传统配置:仅适用于 Spring Boot 2.4-,3.0+ 已废弃
完整代码示例请参考 GitHub 仓库。