背景
目前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); } }); } }