最新国产好看的视频,伊人天堂AV在线,国产Aaaaaa视频,蜜臀视频在线观看一区,人妻av色图,密臀久久久精品影片,青青视频免费观看毛片,久草在线观看视,国产三级精品色情在线

Spring動(dòng)態(tài)監(jiān)聽Nacos配置中心key值變更的實(shí)現(xiàn)方法

 更新時(shí)間:2024年08月15日 10:02:47   作者:qq_34484548  
Nacos本身提供支持監(jiān)聽配置變更的操作,但在使用起來,個(gè)人感覺不是很友好,無法精確到某個(gè)key的變更監(jiān)聽,所以本文小編給大家介紹了Spring動(dòng)態(tài)監(jiān)聽Nacos配置中心key值變更的實(shí)現(xiàn)方法,需要的朋友可以參考下

背景:

Nacos本身提供支持監(jiān)聽配置變更的操作,但在使用起來,個(gè)人感覺不是很友好,無法精確到某個(gè)key的變更監(jiān)聽

實(shí)現(xiàn)方法:

1. 自定義一個(gè)只能用在方法上的注解(當(dāng)然你也可以自定義不僅僅用在方法上)

@Target({ElementType.TYPE, ElementType.METHOD})
@Retention(RetentionPolicy.RUNTIME)
public @interface ConfigListener {
 
    /**
     * 待監(jiān)聽的key或key前綴
     */
    String key();
 
}

2. 添加具體實(shí)現(xiàn)

@Slf4j
@Configuration
public class RefreshEnvironmentConfig implements ApplicationListener<EnvironmentChangeEvent>, EnvironmentAware, BeanPostProcessor {
 
    private Environment environment;
 
    private final Map<String, Map<Method, Object>> listeners = new ConcurrentHashMap<>(64);
 
    private final Set<Class<?>> nonAnnotatedClasses = Collections.newSetFromMap(new ConcurrentHashMap<>(64));
 
    @Override
    public Object postProcessAfterInitialization(Object bean, String beanName) throws BeansException {
        if (!this.nonAnnotatedClasses.contains(bean.getClass())) {
            Class<?> targetClass = AopUtils.getTargetClass(bean);
            Map<Method, ConfigListener> annotatedMethods = MethodIntrospector.selectMethods(targetClass, this::findListenerAnnotations);
            if (!annotatedMethods.isEmpty()) {
                for (Map.Entry<Method, ConfigListener> entry : annotatedMethods.entrySet()) {
                    listeners.computeIfAbsent(entry.getValue().key(), k -> new HashMap<>()).put(entry.getKey(), bean);
                    log.info("Register @ConfigListener methods processed on bean {} listener key {}", beanName, entry.getValue().key());
                }
            }
            this.nonAnnotatedClasses.add(bean.getClass());
        }
        return bean;
 
    }
 
    @Override
    public void onApplicationEvent(EnvironmentChangeEvent event) {
        Set<String> keys = event.getKeys();
        keys.forEach(key -> {
            String value = environment.getProperty(key);
            int index = 0;
            do {
                index = key.indexOf(".", index + 1);
                String subKey = index > 0 ? key.substring(0, index) : key;
                Map<Method, Object> methodMap = listeners.get(subKey);
                if (methodMap != null) {
                    methodMap.forEach((method, bean) -> {
                        try {
                            method.invoke(bean, key, value);
                        } catch (IllegalAccessException | InvocationTargetException e) {
                            log.error("Refresh @ConfigListener {}, error {}", bean, e.getMessage(), e);
                        }
                    });
                }
            } while (index > 0);
        });
    }
 
    @Override
    public void setEnvironment(Environment environment) {
        this.environment = environment;
    }
 
 
    private ConfigListener findListenerAnnotations(Method method) {
        return findListenerAnnotationsByAnnotatedElement(method);
    }
 
    private ConfigListener findListenerAnnotationsByAnnotatedElement(AnnotatedElement element) {
        return AnnotationUtils.findAnnotation(element, ConfigListener.class);
    }
}

3. demo

    @ConfigListener(key = "test.value")
    public void listener1(String key, String newValue) {
        log.info("listener1 listened {}-->{}", key, newValue);
    }
 
    @Async
    @ConfigListener(key = "test")
    public void listener2(String key, String newValue) {
        log.info("listener2 listened {}-->{}", key, newValue);
    }

已上實(shí)現(xiàn),不僅僅適用于Nacos,理論上也適用于其他配置中心,(個(gè)人僅驗(yàn)證過Nacos)

拓展:spring監(jiān)聽nacos配置中心文件變化的兩種方式

1.前置條件

1.1依賴

    <properties>
        <spring-boot.version>2.4.2</spring-boot.version>
        <spring-cloud.version>2020.0.1</spring-cloud.version>
        <spring-cloud-alibaba.version>2021.1</spring-cloud-alibaba.version>
    </properties>
    <dependencies>
        <dependency>
            <groupId>org.springframework.cloud</groupId>
            <artifactId>spring-cloud-starter-bootstrap</artifactId>
        </dependency>
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-webflux</artifactId>
        </dependency>
        <dependency>
            <groupId>com.alibaba.cloud</groupId>
            <artifactId>spring-cloud-starter-alibaba-nacos-config</artifactId>
        </dependency>
        <dependency>
            <groupId>com.alibaba.cloud</groupId>
            <artifactId>spring-cloud-starter-alibaba-nacos-discovery</artifactId>
        </dependency>
    </dependencies>

spring-cloud-starter-bootstrap需要引入

1.2配置

1.2.1 nocos配置

我們要監(jiān)聽other.yaml文件的other.name|age屬性

1.2.2 bootstrap.yml文件內(nèi)容

server:
  port: 8080
---
spring:
  application:
  #需要指定
    name: gateway
  profiles:
    active: dev
---
spring:
  cloud:
    nacos:
      discovery:
      #需要配置
        server-addr: 192.168.56.150:8848
        group: DEFAULT_GROUP
      config:
            #需要配置
        server-addr: 192.168.56.150:8848
        group: DEFAULT_GROUP
        file-extension: yaml
        extension-configs:
          - data-id: gateway-routes.yaml
            group: DEFAULT_GROUP
            refresh: true
          - data-id: other.yaml
            group: DEFAULT_GROUP
            refresh: true

1.3屬性文件映射

@RefreshScope//Bean 在運(yùn)行時(shí)刷新
@ConfigurationProperties(prefix = "other")//要綁定外部屬性的前綴
@Configuration//設(shè)置為bean
public class Config {
	//映射other.yaml ->oher.name
    private String name;
    
    //映射other.yaml ->oher.age
    private String age;
    
    //啟動(dòng)后定時(shí)打印當(dāng)前bean中的值,不推薦這種方式,做測試方法
    @PostConstruct
    public void testValueIsChange() {
        new Thread(() -> {
            int i = 1;
            do {
                Config bean = SpringBeanUtil.getBean(Config.class);
                System.out.println("--- >" + i + "-->當(dāng)前bean值: " + "name:" + bean.getName() + "|age:" + bean.getAge());
                try {
                    Thread.sleep(3000);
                } catch (InterruptedException e) {
                    throw new RuntimeException(e);
                }
                i++;
            } while (true);
        }).start();
    }
    
   //....get/set方法
}  

2監(jiān)聽

2.1第一種方式nacos的SDK

@Component
public class OtherListen {

    @Resource//注入NacosConfigManager
    public void nacosListen(NacosConfigManager nacosConfigManager) {
    	//獲取配置中心服務(wù)
        ConfigService configService = nacosConfigManager.getConfigService();
        try {
        	//對配置中心添加監(jiān)聽(配置文件的dataId,group)
            configService.addListener("other.yaml", "DEFAULT_GROUP", new AbstractConfigChangeListener() {
            	//監(jiān)聽后的處理邏輯
                @Override
                public void receiveConfigChange(ConfigChangeEvent configChangeEvent) {
                    for (ConfigChangeItem changeItem : configChangeEvent.getChangeItems()) {
                        System.out.println("nacos方式監(jiān)聽" + changeItem.getKey() + "-----" + changeItem.getNewValue());
                    }
                }
            });
        } catch (NacosException e) {
            throw new RuntimeException(e);
        }
    }
    
	//注解監(jiān)聽spring.cloud環(huán)境下需要添加額外依賴,可以參考官方文檔,這里不做演示
    @NacosConfigListener(dataId = "other.yaml")
    public void onReceived(String value) {
        System.out.println("onReceived : " + value);
    }
}

2.2第二種方式監(jiān)聽spring的環(huán)境修改

//利用spring事件通知機(jī)制

@Component
public class OtherListen implements ApplicationListener<EnvironmentChangeEvent> {
    @Resource
    private ConfigurableEnvironment environment;
    @Override
    public void onApplicationEvent(EnvironmentChangeEvent event) {
        for (String key : event.getKeys()) {
            System.out.println("spring方式監(jiān)聽: key:" + key + "value:" + environment.getProperty(key));
        }
    }
}

3.測試

  • 啟動(dòng)后,正常讀取到nacos other.yaml數(shù)據(jù)

  • 修改nacos other.yaml數(shù)據(jù)

  • 查看監(jiān)聽是否正常
    spring監(jiān)聽正常

nacosSDk監(jiān)聽正常

到此這篇關(guān)于Spring動(dòng)態(tài)監(jiān)聽Nacos配置中心key值變更的實(shí)現(xiàn)方法的文章就介紹到這了,更多相關(guān)Spring動(dòng)態(tài)監(jiān)聽Nacos key值變更內(nèi)容請搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持腳本之家!

相關(guān)文章

  • Spring MVC 注解自動(dòng)掃描失效原因分析

    Spring MVC 注解自動(dòng)掃描失效原因分析

    這篇文章主要介紹了Spring MVC 注解自動(dòng)掃描失效原因分析,非常不錯(cuò),具有參考借鑒價(jià)值,需要的朋友可以參考下
    2016-07-07
  • 聊聊ResourceBundle和properties讀取配置文件的區(qū)別

    聊聊ResourceBundle和properties讀取配置文件的區(qū)別

    這篇文章主要介紹了ResourceBundle和properties讀取配置文件的區(qū)別,具有很好的參考價(jià)值,希望對大家有所幫助。如有錯(cuò)誤或未考慮完全的地方,望不吝賜教
    2021-07-07
  • Java Tree結(jié)構(gòu)數(shù)據(jù)中查找匹配節(jié)點(diǎn)方式

    Java Tree結(jié)構(gòu)數(shù)據(jù)中查找匹配節(jié)點(diǎn)方式

    這篇文章主要介紹了Java Tree結(jié)構(gòu)數(shù)據(jù)中查找匹配節(jié)點(diǎn)方式,具有很好的參考價(jià)值,希望對大家有所幫助。一起跟隨小編過來看看吧
    2020-09-09
  • 詳解Spring AOP的實(shí)現(xiàn)方式

    詳解Spring AOP的實(shí)現(xiàn)方式

    AOP是一種思想,是對某一類事情的集中處理,切面就是指某一類特定的問題,所以AOP可以理解為面向特定方法編程,這篇文章主要介紹了Spring AOP的實(shí)現(xiàn)方式,需要的朋友可以參考下
    2024-02-02
  • Spring框架十一種常見異常的解決方法匯總

    Spring框架十一種常見異常的解決方法匯總

    今天小編就為大家分享一篇關(guān)于Spring框架十一種常見異常的解決方法匯總,小編覺得內(nèi)容挺不錯(cuò)的,現(xiàn)在分享給大家,具有很好的參考價(jià)值,需要的朋友一起跟隨小編來看看吧
    2019-03-03
  • JVM?jstack實(shí)戰(zhàn)之死鎖問題詳解

    JVM?jstack實(shí)戰(zhàn)之死鎖問題詳解

    如果在生產(chǎn)環(huán)境發(fā)生了死鎖,我們將看到的是部署的程序沒有任何反應(yīng)了,這個(gè)時(shí)候我們可以借助?jstack進(jìn)行分析,下面我們實(shí)戰(zhàn)操作查找死鎖的原因
    2022-10-10
  • 一文了解Seata的實(shí)現(xiàn)原理

    一文了解Seata的實(shí)現(xiàn)原理

    隨著業(yè)務(wù)發(fā)展,單體系統(tǒng)逐漸無法滿足業(yè)務(wù)的需求,分布式架構(gòu)逐漸成為大型互聯(lián)網(wǎng)平臺(tái)首選。伴隨而來的問題是,本地事務(wù)方案已經(jīng)無法滿足,分布式事務(wù)相關(guān)規(guī)范和框架應(yīng)運(yùn)而生。本文主要介紹Seata的實(shí)現(xiàn)原理
    2021-06-06
  • 淺談Spring refresh的工作流程

    淺談Spring refresh的工作流程

    這篇文章主要介紹了淺談Spring refresh的工作流程,refresh 是 AbstractApplicationContext 中的一個(gè)方法,負(fù)責(zé)初始化 ApplicationContext容器,讓我們一起來學(xué)習(xí)一下吧
    2023-04-04
  • Java手寫線程池的實(shí)現(xiàn)方法

    Java手寫線程池的實(shí)現(xiàn)方法

    這篇文章主要為大家詳細(xì)介紹了Java手寫線程池的實(shí)現(xiàn)方法,具有一定的參考價(jià)值,感興趣的小伙伴們可以參考一下
    2018-03-03
  • logback高效狀態(tài)管理器StatusManager源碼解析

    logback高效狀態(tài)管理器StatusManager源碼解析

    這篇文章主要為大家介紹了logback高效狀態(tài)管理器StatusManager源碼解析,有需要的朋友可以借鑒參考下,希望能夠有所幫助,祝大家多多進(jìn)步,早日升職加薪
    2023-11-11

最新評論

馆陶县| 海林市| 隆尧县| 灌阳县| 博乐市| 维西| 永昌县| 青河县| 泰州市| 元谋县| 桐柏县| 西峡县| 平罗县| 广汉市| 澳门| 温泉县| 图片| 沅陵县| 犍为县| 松原市| 都昌县| 昌平区| 桐柏县| 依兰县| 定南县| 保亭| 鱼台县| 兖州市| 洛宁县| 涟水县| 黄石市| 文成县| 泸州市| 华池县| 凤阳县| 来安县| 吐鲁番市| 巨野县| 阳谷县| 辛集市| 清河县|