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


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 就有了我们最新的配置 。
SpringCloudAlibaba 微服务组件 Nacos 之配置中心源码深度解析

文章插图

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

文章插图
至此,我们就实现了配置热更新的效果了 。
总结文章从服务启动时的配置拉取,服务启动后的配置监听器注册,以及配置变动后的热更新实现三个方面从源码层面解析了整个的原理,希望对大家有所帮助 。
个人开源项目DynamicTp 是一个基于配置中心实现的轻量级动态线程池管理工具,主要功能可以总结为动态调参、通知报警、运行监控、三方包线程池管理等几大类 。
SpringCloudAlibaba 微服务组件 Nacos 之配置中心源码深度解析

文章插图
目前累计 2.2k star,欢迎大家试用,感谢你的 star,欢迎 pr,业务之余一起给开源贡献一份力量
官网:https://dynamictp.cn
gitee 地址:https://gitee.com/dromara/dynamic-tp
github 地址:https://github.com/dromara/dynamic-tp

经验总结扩展阅读