Spring的@Value如何從Nacos配置中心獲取值並自動刷新
@Value從Nacos配置中心獲取值並自動刷新
在使用Nacos作為配置中心時,除瞭@NacosValue可以做到自動刷新外,nacos-spring-context:0.3.4版本是支持@Value獲取Nacos配置中心的值,並動態刷新的,該功能是Spri依靠ngValueAnnotationBeanPostProcessor類來實現:
@Override protected Tuple<String, NacosValueTarget> doWithAnnotation(String beanName, Object bean, Value annotation, int modifiers, Method method, Field field) { if (annotation != null) { if (Modifier.isStatic(modifiers)) { return Tuple.empty(); } if (bean.getClass().isAnnotationPresent(NacosRefresh.class)) { String placeholder = resolvePlaceholder(annotation.value()); if (placeholder == null) { return Tuple.empty(); } NacosValueTarget nacosValueTarget = new NacosValueTarget(bean, beanName, method, field); nacosValueTarget.setAnnotationType(getAnnotationType().getSimpleName()); logger.debug("@Value register auto refresh"); return Tuple.of(placeholder, nacosValueTarget); } } return Tuple.empty(); }
分析其源碼可以看到,如果bean上有註解@NacosRefresh,則會自動刷新。
在實際使用時,發現bean上的註解是@Configuration則不會自動刷新,而使用@Component則可以做到自動刷新。
代碼如下:
@NacosRefresh //@Component @Configuration public class BeanTest { @Value("${autofresh.test}") private String testValue; @NacosValue(value="${autofresh.test2}",autoRefreshed = true) private String testValue2; /** * @return the testValue2 */ public String getTestValue2() { return testValue2; } /** * @param testValue2 the testValue2 to set */ public void setTestValue2(String testValue2) { this.testValue2 = testValue2; } /** * @return the testValue */ public String getTestValue() { return testValue; } /** * @param testValue the testValue to set */ public void setTestValue(String testValue) { this.testValue = testValue; } }
測試類:
@Test public void testValueRefreshinNacos() throws InterruptedException { System.out.println(beanTest.getTestValue()); System.out.println(beanTest.getTestValue2()); System.out.println("------修改前"); Thread.sleep(1000*60); System.out.println(beanTest.getTestValue()); System.out.println(beanTest.getTestValue2()); System.out.println("------修改後"); }
這就和@Component與@Configuration的區別有關瞭,@Component註解的bean是原生bean,@Configuration是被cglib動態增加的bean。
Nacos屬性值自動刷新
1.@NacosValue獲取最新值
引入jar包:
<dependency> <groupId>com.alibaba.boot</groupId> <artifactId>nacos-config-spring-boot-starter</artifactId> <version>0.2.7</version> </dependency>
編寫配置類:
@Configuration @EnableNacosConfig(globalProperties = @NacosProperties(serverAddr = "127.0.0.1:8848")) @NacosPropertySource(dataId = "example", group="test",autoRefreshed = true) public class NacosConfiguration { }
編寫測試類:
@Controller public class ConfigController { @NacosValue(value = "${test.data}", autoRefreshed = true) private boolean data; @RequestMapping(value = "/test", method = GET) @ResponseBody public boolean get() { return data; } }
2.@Value獲取最新值
引入jar包:
<dependency> <groupId>com.alibaba.cloud</groupId> <artifactId>spring-cloud-starter-alibaba-nacos-config</artifactId> <version>2.2.1.RELEASE</version> </dependency>
引入配置:
spring: application: name: example cloud: nacos: config: extension-configs[0]: dataId: test.yml group: test refresh: true server-addr: 127.0.0.1:8848 namespace: c845e96f-4423-4618-8c26-5e4d510f566a enabled: true refresh-enabled: true
編寫測試類:
@RestController @RefreshScope public class TestController { @NacosValue(value = "${test.data}", autoRefreshed = true) private String data; @Value(value = "${test.data}") private String datas; @GetMapping("test") public String test() { return "data :" + data + ",datas="+datas; } }
備註:
方式一@NacosValue獲取最新值nacos配置信息需要寫在配置類上
方式二@NacosValue獲取不到值(如果需要使用該註解需要引入方式一的jar,但是不重啟服務獲取不到最新值),@Value獲取最新值一定要加@RefreshScope註解,配置文件中配置refresh: true
以上為個人經驗,希望能給大傢一個參考,也希望大傢多多支持WalkonNet。
推薦閱讀:
- SpringBoot2 整合Nacos組件及環境搭建和入門案例解析
- SpringBoot+Nacos+Kafka微服務流編排的簡單實現
- Java微服務Nacos Config配置中心超詳細講解
- SpringBoot如何整合nacos詳解
- SpringBoot yaml中的數組類型取值方式