关于如何让 static 修饰的字段动态获到取 nacos 的值
前言
在平时的开发中,我们一般使用 nacos 来作为项目的注册中心和配置中心,其中配置中心的动态化配置又是我们经常要用到的设置。配置一些经常发生变化的值特别好用,不需要重启项目,不需要修改代码,只需要在 nacos 的配置文件修改完成,保存一下就可以完成动态配置。这次我想专门记录一下对于 static 修饰的值如何获取到值与动态的刷新该值。
正常使用案例
首先我们先看一下最为经典的用法,也就是非 static 字段的使用,我首先在 nacos 中了如下这么一段配置。
在代码中我是通过下面代码获取到 nacos 配置的值,我个人习惯用 @ConfigurationProperties 指定前缀并搭配 @Configuration 来使用,通过 set 来赋值,同时加一个注解 RefreshScope 来开启动态刷新。
1 |
|
简单写一个方法,打印出来
1 |
|
通过日志我们可以看到获取成功且没有问题,修改值也可以及时更新,这里就不过多赘述,我们进入 static 部分
搭配 static 使用案例
现在我们把所有的字段变为 static,重启代码试一下是否还可以获取到值
1 |
|
很明显,获取到的对象是空的。可以判断出我们修改成了 static,变为静态字段后,初始化是在类加载的时候,早于 nacos 的创建实例阶段,所以我们的字段跟着类加载的时候已经有了默认值,后面 nacos 的值自然赋值不上,除非我们显示的修改,那么我们要如何获取到 nacos 的值呢?
首先先来看一下实体类,与之前唯一不同的地方就是我们只需要手动去创建字段的 get 和 set 方法,注意这里使用 idea 的快捷生成会在方法顺带加上 static 关键字,我们需要手动的把 get 和 set 方法上的 static 删掉。
1 |
|
同时在我们需要使用这个对象的类里,引入 NacosVo 这个对象并初始化。
1 | private static NacosVo nacosVo; |
启动程序,我们可以看到成功获取到了 nacos 中的值,我们尝试改变一下数据发现仍然可以获取到最新的记录,将 nacos 的属性信息赋值给静态字段并实现动态刷新就完成了
原理剖析
我们来看这样一组实例
在程序刚启动后,我分别通过 2 种方式获取 nacos 的配置,打印出的结果是一样的,下面我改变 nacos 的值并重新获取,可以看到,通过 get 方法获取的值是最新的,但是类名获取的仍然是第一次 nacos 的值。
为什么会发生这种情况呢?首先我们需要知道 @RefreshScope 这个注解的作用,这个注解是标记一个 Bean 或者类,在配置发生变化的时候,Spring 会重新创建该容器。而 nacos 也有一个监听类,叫做 NacosConfigProperties,是用来监听 nacos 配置发生变化的,这两个组件的作用下,该 bean 会重新创建。所以后续通过 get 方法获取到的都是从最新的该 bean 中拿到的数据,而类名获取到的则是我们启动框架的时候,初始化进去的当前 nacos 值,同时因为是 static 修饰的,跟着类一起加载,如果后续我们没有进行显示的更改,那么是不会发生变化的。
最后总结一下,NacosConfigProperties 是负责监听 Nacos 配置变化的组件,而 RefreshScope 是负责动态刷新 Bean 的组件。它们一起工作,使得应用程序能够在配置发生变化时自动更新,并实现动态刷新 Bean 的属性值。















