![](http://imgq8.q578.com/ef/1110/f229b3fbafb1ce3f.jpg)
getConfig 方法会调用到 getConfigInner 方法,通过 namespace, dataId, group 唯一定位一个配置文件
首先获取本地缓存文件的配置内容,如果有直接返回
如果步骤 1 从本地没找到相应配置文件,开始从远处拉去,Nacos 2.0 以上版本使用 Grpc 协议进行远程通信,1.0 及以下使用 Http 协议进行远程通信,我们这边以 1.x 为例来解读
![](http://imgq8.q578.com/ef/1110/9f967d05eddb4fb5.jpg)
getServerConfig 方法会构造最终的 http 请求参数进行调用,如果返回 ok,则将返回内容写入到本地缓存文件中,并进行返回。
![](http://imgq8.q578.com/ef/1110/f04c5bee9773b552.jpg)
至此,在项目启动的时候(上下文准备阶段)我们就拉到了远程 Nacos 中的配置,并且封装成 NacosPropertySource 放到了 Spring 的环境变量里。
监听器注册
上面章节我们说了服务启动的时候从远程 Nacos 服务端拉到配置,这个章节我们来说下配置变动怎么实时通知到客户端,首先需要注册监听器。
主要看 NacosContextRefresher 类,该类会监听服务启动发布的 ApplicationReadyEvent 事件,然后进行配置监听器的注册。
![](http://imgq8.q578.com/ef/1110/61dfe8ab5ffba48d.jpg)
registerNacosListenersForApplications 方法里会进行判断,如果自动刷新机制是开启的,则进行监听器注册。上个章节我们说到了会将拉到的配置缓存到 NacosPropertySourceRepository 中, 这儿就从缓存中获取所有的配置,然后循环进行监听器注册(如果配置文件中配置 refresh 字段为 false,则不注册监听器)。
![](http://imgq8.q578.com/ef/1110/fa380db40dfd46c8.jpg)
我们可以看到,监听器是以 dataId + groupId + namespace 为维度进行注册的,监听器的主要操作就三步。
REFRESH_COUNT ++,在上述说的 loadNacosPropertySource 方法有用到
往 NacosRefreshHistory#records 中添加一条刷新记录
发布一个 RefreshEvent 事件,该事件是 SpringCloud 提供的,主要就是用来做环境变更刷新用的
![](http://imgq8.q578.com/ef/1110/3223881f9c5e5587.jpg)
注册操作经过 ConfigService,在 ClientWorker 中处理,这块会创建一个 CacheData 对象,该对象主要就是用来管理监听器的,也是非常重要的一个类。
![](http://imgq8.q578.com/ef/1110/b5ae18a8ef7ce6ae.jpg)
CacheData 中字段如下图,ManagerListenerWrap 对 Listener 做层包装,内部会保存 listener、上次变更的 content 以及 md5(用来判断配置有没有变更用)。
![](http://imgq8.q578.com/ef/1110/dd1e6478fc5df5d6.jpg)
![](http://imgq8.q578.com/ef/1110/ae5cba1b2c82c3d6.jpg)
并且在 addCacheDataIfAbsent 方法中会将刚才创建的 CacheData 缓存到 ClientWorker 中的一个 Map 中,后续会用到。
![](http://imgq8.q578.com/ef/1110/888a48bc6529cd32.jpg)
至此,在服务启动后向每一个需要支持热更新的配置都注册了一个监听器,用来监听远程配置的变动,以及做相应的处理
配置热更新
上面章节我们讲了服务启动的时候从远程 Nacos 服务端拉到配置,以及服务启动后对需要支持热更新的配置都注册了一个监听器,这个章节我们来说下配置变动后具体是怎么处理的。
回到上述说过的 NacosPropertySourceLocator 的 locate 方法看看,该方法首先会获取一个 ConfigService。
![](http://imgq8.q578.com/ef/1110/83ad97cf0d9c65ff.jpg)
NacosConfigManager 中会进行一个 ConfigService 单例对象的创建,创建流程最终会委托给 ConfigFactory,使用反射方式创建一个 NacosConfigService 的实例对象,NacosConfigService 是一个很核心的类,配置的获取,监听器的注册都需要经此。
![](http://imgq8.q578.com/ef/1110/4df56b7f74e1caae.jpg)
我们看下 NacosConfigService 的构造函数,会去创建一个 ClientWorker 类的对象,这个类是实现配置热更新的核心类。