zoukankan      html  css  js  c++  java
  • 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,转载请注明出处,谢谢
  • 相关阅读:
    BZOJ3209: 花神的数论题
    BZOJ3207: 花神的嘲讽计划Ⅰ
    BZOJ3155: Preprefix sum
    BZOJ2465: [中山市选2009]小球
    BZOJ2243: [SDOI2011]染色
    BZOJ1192: [HNOI2006]鬼谷子的钱袋
    hdu1542(线段树——矩形面积并)
    hdu4578(线段树)
    hdu4614(线段树+二分)
    hdu3974(线段树+dfs)
  • 原文地址:https://www.cnblogs.com/liwanping/p/11147143.html
Copyright © 2011-2022 走看看