小知识,大挑战!本文正在参与“程序员必备小知识”创作活动。
配置加载执行路径:loadApplicationConfiguration->loadNacosDataIfPresent->loadNacosPropertySource->build->loadNacosData
可以发现基于configService.getConfig从Nacos配置中心上加载配置返回,事件订阅机制在哪里实现?可查看NacosContextRefresher类,它实现一个ApplicationReadyEvent事件监听,这就是在上下文准备好后触发这个事件。
public class NacosContextRefresher implements ApplicationListener<ApplicationReadyEvent>,ApplicationContextAware{
@Override
public void onApplicationEvent(ApplicationReadyEvent event){
if(this.ready.compareAndSet(false,true)){
this.registerNacosListenerForApplications();
}
}
}
当监听时间到后,会调用registerNacosListenerForApplications方法实现Nacos事件监听的注册
private void registerNacosListener(final String group,final String dataId){
Listener listener = listenerMap.computeIfAbsent(dataId,i->new listener(){
@Override
public void receiveConfigInfo(String configInfo){
refreshHistory.add(dataId,md5);
applicationContext.publishEvent(new RefreshEvent(this,null,"Refresh Nacos Config"));
if(log.isDebugEnabled()){
log.debug("Refresh Nacos config group"+group+",dataId"+dataId);
}
}
});
}
看出当收到配置修改的回调时,通过applicationContext.publishEvent发布一个RefreshEvent事件,这个事件的监听实现在RefreshEventListener类。
public class RefreshEventListener implements SmartApplicationLIstener{
if(this.ready.get()){
log.debug("Event received"+event.getEventDesc());
Set<String> keys=this.refresh.refresh();
log.info("Refresh keys changed:"+keys);
}
}
在handle方法中调用refresh.refresh()方法完成配置的更新。
接着关注客户端和服务端之间的长轮询机制,以及服务端实时推送配置更新信息给客户端。
NacosFactory.createConfigService
客户端的长轮询定时任务是在NacosFactory.createConfigService构建ConfigService对象实例启动
- 通过Class.forName来加载NacosConfigService类
- 使用反射完成NacosConfigService类的实例化
public static ConfigService createConfigService(Properties properties) throws NacosException{
try{
Class<?> driverImplClass = Class.forName("com.alibaba.nacos.client.config.NacosConfigService");
Constructor constructor = driverImplClass.getConstructor(Properties.class);
ConfigService configService = constructor.newInstance(properties);
return configService;
}catch(Throwable e){
throw new NacosExcepion(NacosException.CLIENT_INVALID_PARAM,e);
}
}