SpringCloudAlibaba 微服务组件 Nacos 之配置中心源码深度解析( 三 )


SpringCloudAlibaba 微服务组件 Nacos 之配置中心源码深度解析

文章插图
  1. checkUpdateDataIds 该方法中,会将所有的 dataId 按定义格式拼接出一个字符串,构造一个长轮询请求,发给服务端,Long-Pulling-Timeout 超时时间默认 30s,如果服务端没有配置变更 , 则会保持该请求直到超时,有配置变更则直接返回有变更的 dataId 列表 。

SpringCloudAlibaba 微服务组件 Nacos 之配置中心源码深度解析

文章插图
  1. 拿到第二步有变更的 dataId 后会调用 getServerConfig 获取最新的配置内容 , 然后遍历调用 checkListenerMd5 去检查最新拉取的配置内容的 Md5 跟上次更新的 Md5 是不是一样,不一样则调用 safeNotifyListener 去通知监听器处理,并且更新 listenerWrap 中的 content、Md5

SpringCloudAlibaba 微服务组件 Nacos 之配置中心源码深度解析

文章插图
checkListenerMd5 方法如下,主要就是判断两个 md5 是不是相同 , 不同则调用 safeNotifyListener 处理 。
【SpringCloudAlibaba 微服务组件 Nacos 之配置中心源码深度解析】
SpringCloudAlibaba 微服务组件 Nacos 之配置中心源码深度解析

文章插图
safeNotifyListener 方法主要就是调用监听器的 receiveConfigInfo 方法,然后更新监听器包装器中的 lastContent、lastCallMd5 字段 。
SpringCloudAlibaba 微服务组件 Nacos 之配置中心源码深度解析

文章插图
监听器要执行的方法我们上面也已经讲过了,这边再贴下截图 , 主要就是发布 RefreshEvent 事件 。
SpringCloudAlibaba 微服务组件 Nacos 之配置中心源码深度解析

文章插图
至此,Nacos 的处理流程已经结束了,RefreshEvent 事件主要由 SpringCloud 相关类来处理 。
RefreshEvent 事件处理RefreshEvent 事件会由 RefreshEventListener 来处理,该 listener 含有一个 ContextRefresher 的对象 。
SpringCloudAlibaba 微服务组件 Nacos 之配置中心源码深度解析

文章插图
如下图所示,refreshEnvironment 会去刷新 Spring 环境变量,实际上是交给 updateEnvironment 方法去做的刷新,具体刷新思想就是重新创建一个 Spring 容器,然后将这个新容器中的环境信息设置到原有的 Spring 环境中 。拿到所有变化的配置项后,发布一个环境变化的 EnvironmentChangeEvent 事件 。
SpringCloudAlibaba 微服务组件 Nacos 之配置中心源码深度解析

文章插图

SpringCloudAlibaba 微服务组件 Nacos 之配置中心源码深度解析

文章插图
ConfigurationPropertiesRebinder 会监听 EnvironmentChangeEvent 事件,监听到事件后会对所有的标注有 ConfigurationProperties 注解的配置类进行销毁后重新初始化的操作 , 完之后我们的配置类中的属性就是最新的了 。
SpringCloudAlibaba 微服务组件 Nacos 之配置中心源码深度解析

文章插图

SpringCloudAlibaba 微服务组件 Nacos 之配置中心源码深度解析

文章插图
这里我们说到了会对标有 ConfigurationProperties 注解的配置类进行 rebind,那对于普通组件类里标有 @Value 注解的属性要怎么生效呢?这个其实需要配合 @RefreshScope 注解来生效的 。
我们继续回到上述的 refresh() 方法 , 接着会有一步 refreshAll 的操作,会调用父类的 destroy 方法 。
SpringCloudAlibaba 微服务组件 Nacos 之配置中心源码深度解析

文章插图

SpringCloudAlibaba 微服务组件 Nacos 之配置中心源码深度解析

文章插图
父类就是 GenericScope , 我们知道 Spring 中的 Bean 是有Scope 的概念的,Spring 默认 Scope 有单例和原型两种,同时提供了 Scope 扩展接口,通过实现该接口我们可以定义自己的 Scope 。
SpringCloudAlibaba 微服务组件 Nacos 之配置中心源码深度解析

文章插图
通过doGetBean 方法可以看出,这些自定义 Scope 类型对象的管理会交给相应的 Scope 实现去管理 。
SpringCloudAlibaba 微服务组件 Nacos 之配置中心源码深度解析

文章插图
SpringCloud 实现的 RefreshScope 就是用来在运行时动态刷新 Bean 用的,RefreshScope 继承 GenericScope , 提供 get 和 destroy 方法 。
SpringCloudAlibaba 微服务组件 Nacos 之配置中心源码深度解析

文章插图
GenericScope 内部有一个 cache , 用来保存所有该 Scope 类型的对象 。
SpringCloudAlibaba 微服务组件 Nacos 之配置中心源码深度解析

文章插图
回到主线,所以在 refreshAll 中调用 super.destroy 方法时会将该 scope 的这些 Bean 都销毁掉,在下次 get 的时候在重新创建 Bean,新创建的 Bean 就有了我们最新的配置 。

推荐阅读