环境:SpringBoot2.7.18 + SpringCloud2021.0.7
1. 简介
在Spring Cloud微服务架构中,配置管理是至关重要的。随着业务的发展和服务的不断扩展,配置信息经常需要调整。如何动态地获取这些变化,使服务能够实时响应配置的更新,成为了关键问题。Spring Cloud提供了多种机制来实现配置的动态更新,使得开发人员能够轻松地管理和应用这些变化。
本篇文章不会结合Nacos讲解,将通过其它的方式手动的刷新配置及监听配置文件的变化。
2. 实战案例
2.1 依赖管理
<spring-cloud.version>2021.0.7</spring-cloud.version>
<dependencyManagement>
<dependencies>
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-dependencies</artifactId>
<version>${spring-cloud.version}</version>
<type>pom</type>
<scope>import</scope>
</dependency>
</dependencies>
</dependencyManagement>
项目中主要是需要引入spring-cloud-context包,所以你可以根据需要随便引入openfeign或者loadbalancer相应的包即可,只要环境中存在spring-cloud-context包就行了。本示例引入的是:
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-starter</artifactId>
</dependency>
该依赖中会自动引入commons和context。
2.2 开启bootstrap配置
要启动bootstrap配置(也就是默认的bootstrap.yml配置生效)有以下2中方式:
第一种:
引入下面依赖
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-starter-bootstrap</artifactId>
</dependency>
第二种:
启动应用程序时添加如下参数
-Dspring.cloud.bootstrap.enabled=true
bootstrap.yml配置文件生效关键是BootstrapApplicationListener监听器。
部分代码
public void onApplicationEvent(ApplicationEnvironmentPreparedEvent event) {
ConfigurableEnvironment environment = event.getEnvironment();
if (!bootstrapEnabled(environment) && !useLegacyProcessing(environment)) {
return;
}
// ...
}
推荐第一种方式。
2.3 初始配置
bootstrap.yml配置内容如下
pack:
name: ooxx
对应的属性配置类
@Component("pp")
@ConfigurationProperties(prefix = "pack")
public class PackProperties {
private String name ;
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
}
测试接口
@RestController
@RequestMapping("/pack")
public class PackController {
@Resource(name = "pp")
private PackProperties props ;
@GetMapping("")
public PackProperties p() {
return props ;
}
}
图片
正确显示配置信息。
如果你修改配置文件pack.name默认情况下是不会有任何变化的。要正确的使得配置文件实时更新,我们可以手动的触发配置刷新动作。
触发刷新动作
@Resource
private ContextRefresher contextRefresher ;
@GetMapping("/refresh")
public Object refresh() {
return this.contextRefresher.refresh() ;
}
通过ContextRefresher#refresh方法会触发2个核心动作:
- 重新初始化refresh作用域的bean对象
- @ConfigurationProperties注解的类(或方法@Bean)会重新初始化触发EnvironmentChangeEvent事件。
修改配置文件内容如下:
pack:
name: ooxx
调用上面/refresh接口后,无需重启服务,配置信息已经动态刷新
图片
上面的示例是需要对@ConfigurationProperties进行重写绑定,所以我们可以通过监听EnvironmentChangeEvent事件在程序中监听配置的变化。
@Component
public class PackApplicationEventListener implements ApplicationListener<EnvironmentChangeEvent> {
@Resource
private Environment env ;
@Override
public void onApplicationEvent(EnvironmentChangeEvent event) {
System.out.println(event.getKeys()) ;
System.out.println(env.getProperty("pack.name")) ;
}
}
当配置发生变化后,上面的监听程序将被触发。
控制台输出
[pack.name]
xxxooo