Apollo 本身是可以基于事件监听实时推送(Http长连接)变更(AutoUpdateConfigChangeListener),也会定时拉取(fallback)最新配置。
如果说我们还需要在配置更新时,做一些其他的业务,比如:对配置做了一些自己的数据缓存,或者业务变更等,那么我们需要控制监听器,apollo提供了这样的策略。可手动配置一个监听器在容器中。
有两种方式如下:
一、手动代码初始化监听器并配置到Config上下文中
@SpringBootApplication public class ConfigApplication { public static void main(String[] args) { SpringApplication.run(ConfigApplication.class, args); // 手动配置 apolloConfigListener,添加配置改动监听 ConfigChangeListener configChangeListener = new ConfigChangeListener() { @Override public void onChange(ConfigChangeEvent configChangeEvent) { ConfigChange change; for (String key : configChangeEvent.changedKeys()) { change = configChangeEvent.getChange(key); // 打印改动的配置信息 System.out.println( String.format(String.format("Change - key: %s, oldValue: %s, newValue: %s, changeType: %s", change.getPropertyName(), change.getOldValue(), change.getNewValue(), change.getChangeType()))); } } }; // 也可@ApolloConfig注入 ConfigService.getAppConfig().addChangeListener(configChangeListener); } }
这里我将实现过程写在启动类中,手动实现一个匿名类ConfigListener然后配置到Config中,ConfigService.getAppConfig()是Apollo提供的静态方法,用于获取当前容器默认的ApolloConfig,默认是指的namespace是默认“application”,也就是说获取的是“application”的config,上面这样操作,监听的是application。
可以看到getAppConfig的实现:
如果想要获得其他namespace的话,getConfig(“namespace”),形参为你所指定的namespace,然后addChangeListener(),即可以监听指定namespace下的配置变换。可以理解Config是namespace维度下的,每个namespace(同一应用,同一集群,同一环境)下都一个Config。
支持监听namespace下指定配置key,提供三个重载方法,默认无参的,则监听namespace下所有key,下图中第一个方法监听指定key,第二个监听指定以其开头的key。
使用如下:
config.addChangeListener(configChangeListener, new HashSet<String>(){{ add("nwpu.name"); }}, new HashSet<String>(){{ add("nwpu"); }});
二、用@ApolloConfigChangeListener注解标记,自动注册ConfigChangeListener
@Configuration public class ApolloConfig { @Autowired private RefreshScope refreshScope; @ApolloConfigChangeListener(value = {"application", "datasource"}) private void onChangeToAll(ConfigChangeEvent changeEvent) { ConfigChange change; for (String key : changeEvent.changedKeys()) { // 如果@ConfigurationProperties配置发生变化,则需要手动刷新 // if (key.substring(0, 5).equals("nwpu")) { // refreshScope.refresh("nwpuDTO"); // } change = changeEvent.getChange(key); // 打印出新增或者变化的配置 相关信息 System.out.println(String.format("Change - key: %s, oldValue: %s, newValue: %s, changeType: %s", change.getPropertyName(), change.getOldValue(), change.getNewValue(), change.getChangeType())); } } @ApolloConfigChangeListener(value = "application", interestedKeyPrefixes = "nwpu") private void onChangeToApplication(ConfigChangeEvent changeEvent) { ConfigChange change; for (String key : changeEvent.changedKeys()) { // 如果@ConfigurationProperties配置发生变化,则需要手动刷新 refreshScope.refresh("nwpuDTO"); change = changeEvent.getChange(key); // 打印出新增或者变化的配置 相关信息 System.out.println(String.format("Change - key: %s, oldValue: %s, newValue: %s, changeType: %s", change.getPropertyName(), change.getOldValue(), change.getNewValue(), change.getChangeType())); } } }
这种方式应该是用注解标记,然后aop切面标记的方法,然后注入Config中。标记方法的实现是配置变化后的处理业务。
分析上面的代码,我们总共对两个config操作,一个application config,一个datasource config,然后分别注册监听器,注意application注册两次监听器,第一次没有指定key,第二次指定了key前缀,测试发现均可用,也就是说config允许同时注册多个监听器。
发表评论