• Apollo实现@ConfigurationProperties配置刷新的另一种方式


    背景

    目前apollo官方实现@ConfigurationProperties需要配合使用EnvironmentChangeEvent或RefreshScope(需要引入springCloud-context),考虑一种简单的实现方式如下:

    思路

    监听apollo配置刷新事件,然后通过spring的工具类获取当前配置类的bean实例对象(单例),通过反射将对应改变的配置项注入配置类bean实例。

    代码实现

    @Data
    @Slf4j
    @Configuration
    @ConfigurationProperties
    @EnableApolloConfig
    public class AppConfig {
    
        private Map<String, String> xxConfigMap;
    
        @ApolloConfigChangeListener
        public void onChange(ConfigChangeEvent changeEvent) {
            //this.applicationContext.publishEvent(new EnvironmentChangeEvent(changeEvent.changedKeys()));
       changeEvent.changedKeys().stream().map(changeEvent::getChange).forEach(change -> {
                log.info("Found change - key: {}, oldValue: {}, newValue: {}, changeType: {}", change.getPropertyName(), change.getOldValue(), change.getNewValue(), change.getChangeType());
                String vKey = change.getPropertyName();
                String newValue = change.getNewValue();
                if (vKey.contains(".")) {
                    //取出对应的field 反射重新赋值
                    AppConfig appConfig = SpringContext.getBean(AppConfig.class);
                    try {
                        PropertyDescriptor propertyDescriptor = new PropertyDescriptor(vKey.substring(0, vKey.indexOf(".")), appConfig.getClass());
                        Map<String, String> map = (Map<String, String>) propertyDescriptor.getReadMethod().invoke(appConfig);
                        map.put(vKey.substring(vKey.indexOf(".")+1,vKey.length()), newValue);
                        propertyDescriptor.getWriteMethod().invoke(appConfig, map);
                    } catch (Exception e) {
                        log.error("replace field {} error", vKey);
                    }
                }
            });
        }
    
    
        //测试是否生效
        @PostConstruct
        void test() {
            Executors.newSingleThreadExecutor().submit(() -> {
                while (true) {
                    log.info(xxConfigMap.toString());
                    Thread.sleep(2000);
                }
            });
        }
    }
    

    Reference

    apollo wiki spring-boot集成方式

    =====原文作者博客园----dustyhope,转载请注明出处,谢谢
  • 相关阅读:
    http请求头和响应头详细解释
    http协议POST请求头content-type主要的四种取值
    什么是精准测试
    测试管理(管事篇)
    有赞全链路压测方案设计与实施详解
    饿了么全链路压测平台的实现与原理
    京东全链路压测军演系统(ForceBot)架构解密
    java Apache common-io 讲解
    CentOS 7.0 安装go 1.3.1
    异常
  • 原文地址:https://www.cnblogs.com/liwanping/p/11147143.html
Copyright © 2020-2023  润新知