一、第一种方式
@ConfigurationProperties不能自动刷新,需要手动调用contextRefresher.refresh()方法来刷新配置。
import org.springframework.boot.context.properties.ConfigurationProperties;
import org.springframework.stereotype.Component;
@Component
@ConfigurationProperties(prefix = "biz")
public class BizConfig {
private String key;
private Long refresh;
//省略 gettersetter...
}
二、第二种方式
@RefreshScope 注解可以使得这个类具备刷新功能,可以在配置文件内容变更后,刷新并更新这个配置类的属性值。
import org.springframework.beans.factory.annotation.Value;
import org.springframework.cloud.context.config.annotation.RefreshScope;
import org.springframework.stereotype.Component;
/**
*
* @RefreshScope 注解可以使得这个类具备刷新功能,可以在配置文件内容变更后,刷新并更新这个配置类的属性值。使用@RefreshScope注解,仅仅只能刷新@Value的配置属性。
*
* 在这个配置类中,使用了 @Value 注解注入了一个属性 uuid,该属性的值来源于配置文件中 rest.uuid 属性的值。
* 由于该配置类使用了 @RefreshScope 注解,所以如果配置文件中 rest.uuid 的值发生变化,
* Spring Cloud Config Server 就会通知该配置类,然后调用 setUuid() 方法刷新该属性的值,从而实现了动态刷新配置的效果。
*
*
* 如果使用@RefreshScope注解,仅仅只能刷新@Value的配置属性,
* 而对于@ConfigurationProperties则不能自动刷新,需要手动调用contextRefresher.refresh()方法来刷新配置。
*
* 因此,在DemoController中的refresh()方法,通过开启一个新的线程来异步调用contextRefresher.refresh()方法,
* 实现对@ConfigurationProperties的刷新。这样就可以保证对于@Value和@ConfigurationProperties两种配置属性都可以进行刷新。
*/
@RefreshScope
@Component
public class ValueConfig {
@Value("${rest.uuid}")
private String uuid;
// 省略 gettersetter
}
使用 contextRefresher.refresh() 刷新
import com.alibaba.fastjson.JSONObject;
import com.lfsun.bootdynamicrefresh.config.BizConfig;
import com.lfsun.bootdynamicrefresh.config.ValueConfig;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.cloud.context.refresh.ContextRefresher;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RestController;
@RestController
public class DemoController {
@Autowired
private ContextRefresher contextRefresher;
@Autowired
private BizConfig bizConfig;
@Autowired
private ValueConfig valueConfig;
/**
* 查询配置信息
*/
@GetMapping(path = "/show")
public String show() {
JSONObject res = new JSONObject();
res.put("biz", JSONObject.toJSONString(bizConfig));
res.put("uuid", valueConfig.getUuid());
return res.toJSONString();
}
/**
* 刷新配置信息
*/
@GetMapping(path = "/refresh")
public String refresh() {
// 新开一个线程进行配置信息的刷新,避免阻塞其他请求的处理
new Thread(() -> contextRefresher.refresh()).start();
// 返回刷新后的配置信息
return show();
}
}
配置文件 application.yml
biz:
refresh: ${random.long}
key: refresh-test
rest:
uuid: ${random.uuid}
server:
port: 8081
pom.xml
<dependencies>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-web</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-context</artifactId>
</dependency>
<dependency>
<groupId>org.projectlombok</groupId>
<artifactId>lombok</artifactId>
</dependency>
</dependencies>
<dependencyManagement>
<dependencies>
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-dependencies</artifactId>
<version>Finchley.RELEASE</version>
<type>pom</type>
<scope>import</scope>
</dependency>
</dependencies>
</dependencyManagement>
实现效果
http://localhost:8081/show/
http://localhost:8081/refresh/