一、第一种方式
@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 {@Autowiredprivate ContextRefresher contextRefresher;@Autowiredprivate BizConfig bizConfig;@Autowiredprivate 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-testrest: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/