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 服務器
為了外部化配置文件,我們使用 Spring Cloud Config 創建邊緣服務。 它作為配置文件的分發服務器。 在本文中,我們將使用文件系統存儲庫。
2.1. 創建配置文件
應用程序中定義的配置信息會共享給所有客户端應用程序。 此外,還可以為應用程序或特定 profile 定義特定的配置。
讓我們從創建一個包含為客户端應用程序提供的屬性的配置文件開始。 我們將客户端應用程序命名為“baeldung”。 在 /resources/config 文件夾中,讓我們創建一個名為 baeldung.properties 的文件。
2.2. 添加屬性
讓我們為我們的 baeldung.properties 文件添加一些屬性,然後我們將使用這些屬性在我們的客户端應用程序中:
hello=Hello Jane Doe!
welcome=Welcome Jane Doe!讓我們在 resources/config/application.properties文件中添加一個共享屬性,Spring 將會將其共享到所有客户端:
shared-property=This property is shared accross all client applications2.3. Spring-Boot 配置服務器應用程序
現在,讓我們創建一個將提供配置的 Spring 應用程序。 我們還需要以下依賴項:spring-cloud-config-server。
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-config-server</artifactId>
</dependency>一旦安裝完成,我們接下來創建應用程序並啓用配置服務器:
@SpringBootApplication
@EnableConfigServer
public class ConfigServer {
public static void main(String[] args) {
SpringApplication.run(ConfigServer.class, args);
}
}讓我們在應用程序的 application.properties 文件中添加以下屬性,以指示它在 8081 端口啓動,並加載先前定義的配置:
server.port=8081
spring.cloud.config.server.native.searchLocations=classpath:/config現在,讓我們啓動我們的服務器應用程序,激活原生配置文件,並允許我們使用文件系統作為配置存儲庫:
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"
}
}
]
}
我們向服務器指示我們的應用程序名稱以及使用的配置文件,即default。
我們尚未禁用spring.cloud.config.server.accept-empty屬性,該屬性默認值為true。如果應用程序未被識別(unknownclient),配置服務器仍然返回共享的屬性。
3. 客户端應用程序
現在,讓我們創建一個客户端應用程序,該應用程序在啓動時加載由我們的服務器提供的配置。
3.1. 項目設置與依賴
讓我們添加 spring-cloud-starter-config 依賴項以加載配置,以及 spring-boot-starter-web 以在我們的 pom.xml 中創建控制器:
<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. 創建客户端應用程序
接下來,讓我們創建一個客户端應用程序,該應用程序將從我們的 spring-cloud-config 服務器讀取配置:
@SpringBootApplication
public class Client {
public static void main(String[] args) {
SpringApplication.run(Client.class, args);
}
}3.3. 從服務器獲取配置
讓我們修改我們的 application.properties 文件,告知 spring-boot 從我們的服務器獲取配置:
spring.cloud.config.name=baeldung
spring.config.import=optional:configserver:http://localhost:8081我們還指定了我們的應用程序的名稱為“baeldung”,以便充分利用其專用屬性。
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;
}
}現在我們可以通過以下三個 URL 進行導航,以驗證我們的配置是否已生效:
$ 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 applications4. 在服務器端覆蓋屬性
可以通過修改服務器配置來覆蓋給定應用程序中定義的屬性。
請編輯服務器的 <em >resources/application.properties</em> 文件,以覆蓋 <em >hello</em> 屬性:
spring.cloud.config.server.overrides.hello=Hello Jane Doe – application.properties!讓我們再次測試對 /hello 控制器的調用,以驗證過載是否已得到考慮:
$ curl http://localhost:8080/hello
Hello Jane Doe - application.properties!可以在 resources/config/application.properties 文件中添加此重載。 在這種情況下,它將優先於上面定義的那個
5. 客户端側覆蓋屬性
自 Spring Boot 2.4 版本起,不再可以通過客户端應用程序的 <em >application.properties</em > 文件覆蓋屬性。
5.1. 使用 Spring 配置文件
我們可以使用 Spring 配置文件。 本地配置的 Spring 配置文件優先級高於服務器級別的應用程序配置優先級。
讓我們為我們的客户端應用程序添加一個 application-development.properties 配置文件,並覆蓋 hello 屬性:
hello=Hello local property!現在,讓我們通過激活開發配置文件來啓動我們的客户端:
mvn spring-boot:run -Drun.profiles=development我們現在可以再次測試我們的控制器 hello</em/>,以驗證重載是否正確工作:
$ curl http://localhost:8080/hello
Hello local property!5.2. 使用佔位符
我們可以使用佔位符來值定屬性。 因此,服務器將提供默認值,該值可以被客户端定義的屬性覆蓋。
讓我們從服務器的 resources/application.properties 文件中移除 hello 屬性的重載,並將 config/baeldung.properties 中的內容修改為包含佔位符:
hello=${app.hello:Hello Jane Doe!}因此,服務器提供了一個默認值,如果客户端聲明瞭名為 app.hello 的屬性,則可以覆蓋該值。
讓我們編輯客户端的 resources/application.properties 文件以添加該屬性:
app.hello=Hello, overriden local property!讓我們再次測試我們的 controller hello,以驗證過電壓是否正確計算:
$ curl http://localhost:8080/hello
Hello, overriden local property!請注意,如果 hello 屬性也在配置文件中定義,則後者的優先級更高。
6. 遺留配置
自 Spring Boot 2.4 版本起,就可以使用“遺留配置”。這允許我們使用在 Spring Boot 2.4 版本變更之前的老舊屬性管理系統。
6.1. 加載外部配置
在 2.4 版本之前,外部配置的管理通過一個引導程序(bootstrap)來保證。我們需要添加 spring-cloud-starter-bootstrap 依賴。下面我們在 pom.xml 中添加它:
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-starter-bootstrap</artifactId>
</dependency>接下來,我們將創建一個 bootstrap.properties 文件,並配置訪問 URL 到我們的服務器:
spring.cloud.config.name=baeldung
spring.cloud.config.uri=http://localhost:8081讓我們在 application.properties 中啓用遺留配置:
spring.config.use-legacy-processing=true6.2. 啓用覆蓋能力
在服務器端,我們需要指示屬性覆蓋是允許的。請修改我們的 <em>baeldung.properties</em> 文件如下:
spring.cloud.config.overrideNone=true因此,外部屬性不會優先於在應用程序 JAR 中定義的屬性。
6.3. 覆蓋服務器屬性
我們可以通過在 application.properties 文件中設置,來覆蓋客户端應用程序中的 hello 屬性:
hello=localproperty讓我們測試對控制器的調用:
$ curl http://localhost:8080/hello
localproperty6.4. 遺留配置的廢棄
自 Spring Boot 3.0 版本起,無法啓用遺留配置。在這種情況下,我們應該使用上述其他方法。
7. 結論
在本文中,我們探討了在 Spring Cloud Config 中覆蓋遠程屬性的不同方法。
可以從服務器端覆蓋針對特定應用程序定義的屬性。此外,還可以使用 profiles 或佔位符在客户端級別覆蓋屬性。 我們還研究瞭如何激活遺留配置以返回舊的屬性管理系統。