欧美bbbwbbbw肥妇,免费乱码人妻系列日韩,一级黄片

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

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

背景:

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

實現(xiàn)方法:

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

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

2. 添加具體實現(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);
    }

已上實現(xiàn),不僅僅適用于Nacos,理論上也適用于其他配置中心,(個人僅驗證過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 在運行時刷新
@ConfigurationProperties(prefix = "other")//要綁定外部屬性的前綴
@Configuration//設(shè)置為bean
public class Config {
	//映射other.yaml ->oher.name
    private String name;
    
    //映射other.yaml ->oher.age
    private String age;
    
    //啟動后定時打印當前bean中的值,不推薦這種方式,做測試方法
    @PostConstruct
    public void testValueIsChange() {
        new Thread(() -> {
            int i = 1;
            do {
                Config bean = SpringBeanUtil.getBean(Config.class);
                System.out.println("--- >" + i + "-->當前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事件通知機制

@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.測試

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

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

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

nacosSDk監(jiān)聽正常

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

相關(guān)文章

  • Spring Data JPA中的動態(tài)查詢實例

    Spring Data JPA中的動態(tài)查詢實例

    本篇文章主要介紹了詳解Spring Data JPA中的動態(tài)查詢。小編覺得挺不錯的,現(xiàn)在分享給大家,也給大家做個參考。一起跟隨小編過來看看吧
    2017-04-04
  • 圖文詳解Maven工程打jar包的N種方式

    圖文詳解Maven工程打jar包的N種方式

    最近在打包maven項目時,該項目中僅有一個測試類,想打成jar包運行測試,所以下面這篇文章主要給大家介紹了關(guān)于Maven工程打jar包的N種方式,文中通過實例代碼介紹的非常詳細,需要的朋友可以參考下
    2022-09-09
  • 帶你了解Java數(shù)據(jù)結(jié)構(gòu)和算法之高級排序

    帶你了解Java數(shù)據(jù)結(jié)構(gòu)和算法之高級排序

    這篇文章主要為大家介紹了Java數(shù)據(jù)結(jié)構(gòu)和算法之高級排序,具有一定的參考價值,感興趣的小伙伴們可以參考一下,希望能夠給你帶來幫助
    2022-01-01
  • SpringBoot?項目打成?jar后加載外部配置文件的操作方法

    SpringBoot?項目打成?jar后加載外部配置文件的操作方法

    這篇文章主要介紹了SpringBoot?項目打成?jar后加載外部配置文件的操作方法,本文給大家介紹的非常詳細,對大家的學(xué)習(xí)或工作具有一定的參考借鑒價值,需要的朋友可以參考下
    2023-03-03
  • Java中equals與==的用法和區(qū)別

    Java中equals與==的用法和區(qū)別

    這篇文章主要給大家介紹了關(guān)于Java中equals與==的用法和區(qū)別的相關(guān)資料,文中通過示例代碼介紹的非常詳細,對大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價值,需要的朋友們下面隨著小編來一起學(xué)習(xí)學(xué)習(xí)吧
    2018-11-11
  • IntelliJ IDEA設(shè)置Tabs實現(xiàn)同時打開多個文件且分行顯示

    IntelliJ IDEA設(shè)置Tabs實現(xiàn)同時打開多個文件且分行顯示

    今天小編就為大家分享一篇關(guān)于IntelliJ IDEA設(shè)置Tabs實現(xiàn)同時打開多個文件且分行顯示,小編覺得內(nèi)容挺不錯的,現(xiàn)在分享給大家,具有很好的參考價值,需要的朋友一起跟隨小編來看看吧
    2018-10-10
  • Jmeter非GUI模式運行分布式測試

    Jmeter非GUI模式運行分布式測試

    這篇文章主要介紹了Jmeter非GUI模式運行分布式測試,文中通過示例代碼介紹的非常詳細,對大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價值,需要的朋友可以參考下
    2020-10-10
  • java中Memcached的使用實例(包括與Spring整合)

    java中Memcached的使用實例(包括與Spring整合)

    這篇文章主要介紹了java中Memcached的使用實例(包括與Spring整合),具有很好的參考價值,希望對大家有所幫助。如有錯誤或未考慮完全的地方,望不吝賜教
    2021-07-07
  • Java模擬撲克牌洗牌實現(xiàn)生成52張撲克的方法示例

    Java模擬撲克牌洗牌實現(xiàn)生成52張撲克的方法示例

    這篇文章主要介紹了Java模擬撲克牌洗牌實現(xiàn)生成52張撲克的方法,涉及Java數(shù)組遍歷、重排及輸出等相關(guān)操作技巧,需要的朋友可以參考下
    2018-01-01
  • java讀取excel表格的方法

    java讀取excel表格的方法

    這篇文章主要為大家詳細介紹了java讀取excel表格的方法,文中示例代碼介紹的非常詳細,具有一定的參考價值,感興趣的小伙伴們可以參考一下
    2020-12-12

最新評論