Spring的@Value如何從Nacos配置中心獲取值并自動刷新
@Value從Nacos配置中心獲取值并自動刷新
在使用Nacos作為配置中心時,除了@NacosValue可以做到自動刷新外,nacos-spring-context:0.3.4版本是支持@Value獲取Nacos配置中心的值,并動態(tài)刷新的,該功能是Spri依靠ngValueAnnotationBeanPostProcessor類來實現(xiàn):
@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,則會自動刷新。
在實際使用時,發(fā)現(xiàn)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的區(qū)別有關了,@Component注解的bean是原生bean,@Configuration是被cglib動態(tài)增加的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
以上為個人經驗,希望能給大家一個參考,也希望大家多多支持腳本之家。
相關文章
@CacheEvict 清除多個key的實現(xiàn)方式
這篇文章主要介紹了@CacheEvict 清除多個key的實現(xiàn)方式,具有很好的參考價值,希望對大家有所幫助。一起跟隨小編過來看看吧2021-02-02Java反射根據(jù)不同方法名動態(tài)調用不同的方法(實例)
下面小編就為大家?guī)硪黄狫ava反射根據(jù)不同方法名動態(tài)調用不同的方法(實例)。小編覺得挺不錯的,現(xiàn)在就分享給大家,也給大家做個參考。一起跟隨小編過來看看吧2016-08-08Java數(shù)據(jù)結構實現(xiàn)二維數(shù)組與稀疏數(shù)組轉換詳解
稀疏數(shù)組是用于優(yōu)化,壓縮具有以下特點的二維數(shù)組:當二維數(shù)組中的元素大部分相同,有意義的數(shù)據(jù)元素較少時,可以使用稀疏數(shù)組進行簡化,節(jié)省存儲空間2021-10-10SpringBoot整合RabbitMQ實現(xiàn)六種工作模式的示例
這篇文章主要介紹了SpringBoot整合RabbitMQ實現(xiàn)六種工作模式,本文通過實例代碼給大家介紹的非常詳細,對大家的學習或工作具有一定的參考借鑒價值,需要的朋友可以參考下2022-07-07Java的ConcurrentLinkedQueue源碼分析
這篇文章主要介紹了Java的ConcurrentLinkedQueue源碼分析,ConcurrentLinkedQueue 是一個基于鏈接節(jié)點的無界線程安全的隊列,當我們添加一個元素的時候,它會添加到隊列的尾部,當我們獲取一個元素時,它會返回隊列頭部的元素,需要的朋友可以參考下2023-12-12