配置及时更新原理(spring context)
注解实现:@RefreshScope
@RestController
@RefreshScope
public class TestController {
@Value("${some.config:}")
private String someConfig;
@GetMapping("/test")
public String test() {
return someConfig;
}
}
原理:
@RefreshScope是Spring Cloud Config提供的一种机制,用于实现配置的动态刷新。在Spring Cloud Alibaba Nacos中,也可以使用这个注解来实现Nacos配置的实时更新。
当一个bean被@RefreshScope注解标记时,它就会在Spring的环境上下文中被特殊处理。这个bean不会像普通的单例bean那样只被创建一次,而是会在需要时被创建和销毁。当环境中的配置变化时,这个bean会被重新创建,以获取最新的配置信息。
在Spring Cloud Alibaba Nacos中,当Nacos配置中心的配置信息发生变化时,会触发一个EnvironmentChangeEvent。Spring Boot会监听这个事件,当事件发生时,会清空所有@RefreshScope标记的bean,使它们在下次访问时被重新创建。
这就是@RefreshScope实现Nacos配置实时更新的基本原理。但是需要注意的是,只有当你访问@RefreshScope标记的bean时,它才会被重新创建。如果你的应用在配置变化后没有访问这个bean,那么这个bean就不会被更新。
事件监听:
@EventListener
public void handle(EnvironmentChangeEvent event) {
for (String key : event.getKeys()) {
if (key.startsWith("nacos.config")) {
// 这个属性可能是由Nacos改变的
System.out.println("Nacos config changed: " + key);
}
}
}
注意:
如果你的配置是以spring.cloud.nacos.config.shared-dataids或spring.cloud.nacos.config.extension-configs的方式配置的,那么在配置更新时,你需要手动调用NacosConfigProperties的reload方法来重新加载配置
取不到值的原因
@GetMapping("/test")
public String test() {
方法是private不是public,默认cglib,修改@RefreshScope的proxyMode属性
将proxyMode改为ScopedProxyMode.DEFAULT或者ScopedProxyMode.NO
@ConfigurationProperties
@Component
@ConfigurationProperties(prefix = "some.config")
@RefreshScope
public class SomeConfigProperties {
private String property;
// getter and setter methods
}