背景
目前apollo官方实现@ConfigurationProperties须要配合使用EnvironmentChangeEvent或RefreshScope(须要引入springCloud-context),考虑一种简单的实现方式以下:java
思路
监听apollo配置刷新事件,而后经过spring的工具类获取当前配置类的bean实例对象(单例),经过反射将对应改变的配置项注入配置类bean实例。git
代码实现
@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); } }); } }