SpringCloud之如何配置文件自动刷新配置

1. 刷新环境Environment的理论分析

在之前我们已经提过bootstrap配置文件的生效,是直接在BootstrapApplicationListener中建立一个隔离的bootstrap容器,从而得到刷新完成的容器的环境对象,并和app容器的环境对象去进行合并。

我们知道bootstrap配置文件自然是为了实现SpringCloud中很重要的一环,那就是分布式配置中心,我们下面以Nacos为例。

首先我们知道只要启动app容器,并且里面包含了BootstrapApplicationListener这个监听器,那么就会启动bootstrap容器,并将里面的ApplicationContext的初始化器转移到app容器当中去,当ApplicationContext创建好时,就会自动回调ApplicationContext的初始化器。

而其中一个组件PropertySourceBootstrapConfiguration,它会自动注入容器中所有的类型的PropertySourceLocator组件。

image.png

在它对ApplicationContext去进行准备工作的回调方法如下

image.png

我们可以看到,它做的事情就是遍历所有的Locator,去执行它的locateCollection方法。

image.png

我们可以看到,locateCollection方法其实就是回调locate方法,去加载属性源(PropertySource,也就是对配置文件的抽象)。

Nacos中就实现了这样一个组件NacosPropertySourceLocator

image.png

我们可以发现,这就是去ConfigServer当中去加载配置文件的逻辑。

从以上的分析当中,我们可以知道,构建一个app容器,就能得到完整的环境信息。实际上是依赖BootstrapApplicationListener去构建的隔离容器,最终实现的ConfigServer中配置文件的加载。

其实在Spring中就是这样去做的,构建一个mini版本的app容器,因为容器就会去回调Locator,因此就能得到完整的环境信息。再将该容器的环境信息,和真正的app容器去进行合并,就得到了更新之后的环境信息。

2. 在Spring当中的落地实现

自动刷新的入口在RefreshEventListener这个组件

image.png

我们可以看到,它监听了RefreshEvent事件,当这个事件被发布时,就会回调ContextRefresherrefresh方法去完成配置文件的刷新工作。

image.png

从上面的代码中,我们可以将其分为三步:

  • 1.updateEnvironment,更新环境对象,它是一个模板方法,交给子类去进行实现。
  • 2.发布EnvironmentChangeEvent事件。
  • 3.scope.refreshAll

2.1 更新环境信息

我们先来看第一步(找到子类LegacyContextRefresherupdateEnvironment方法)

image.png

我们可以看到,其实这就是构建一个mini的app容器,并设置监听器为BootstrapApplicationListener,在刷新完容器,拿到它执行完成的环境对象,去更新原来的app环境当中的环境信息。

2.2 发布环境改变事件并进行rebind

接着来看第二步,发布EnvironmentChangeEvent事件,其中一个组件ConfigurationPropertiesRebinder,就监听了这个事件。

image.png

我们可以看到,当环境发生改变的事件发布之后,它就会遍历所有的标有@ConfigurationProperties注解的Bean去进行rebind,下面我们来看rebind做了什么?

image.png

我们可以看到,首先是摧毁Bean,然后就是对Bean去进行重新初始化(重新初始化的过程中,就会有处理@ConfigurationProperties注解的Bean去进行值的设置)

我们来看ConfigurationPropertiesBeans这个组件是如何收集@ConfigurationProperties的组件的?

image.png

我们可以看到,它是一个BeanPostProcessor,可以在Bean初始化前后去进行干预,它首先把RefreshScopeBean给排除掉,再去扫描@ConfigruationProperties注解,也就是说,它维护的是非RefreshScope,并且标注了@ConfigurationProperties注解的组件。

2.3 刷新RefreshScope作用域内的Bean

image.png
image.png

我们可以看到,它先将自己的作用域的Bean去进行destory(将自己这个作用域内的Bean的缓存直接清空,并完成destroy回调),然后发布RefreshScopeRefreshedEvent事件。

RefreshScope这个作用域被刷新时,代表下次获取RefreshScope内的Bean时,就得重新调用createBean方法去创建一个Bean,重新创建,自然是会拿到新的配置信息,能实现刷新效果,没毛病。

如何让自己成为一个RefreshScopeBean呢?给一个Bean上标上@RefreshScope注解即可。

2.4 用到的相关组件从何而来?

cloud-context包的spring.factories当中配置了下面这个配置类,会给容器中导入ConfigurationPropertiesBeansConfigurationPropertiesRebinder组件,去支持@ConfigurationProperties注解的Beanrebind

image.png

2.5 Nacos如何整合Spring去进行发布事件?

Nacos通过spring.factories给容器中导入了NacosConfigAutoConfiguration这个组件,这个组件内部给容器中导入了一堆组件。

image.png

其中我们需要关注的组件是NacosContextRefresher

image.png

这个组件它也是一个监听器,负责监听容器已经启动完成的事件,当容器启动完成的事件发布之后,它就会将已经注册的全部属性源的dataId配合group,注册一个监听器到NacosConfigService当中去,而监听器内部做的事就是发布RefreshEvent事件。

image.png

NacosConfigServer中的配置信息发生了改变,就会推送消息给NacosClient,而此时NacosClient就会回调相应的监听器,回调监听器时,自然就肯定会发布RefreshEvent事件。

RefreshEvent事件到来时,就会触发我们上面提到的刷新工作,将@ConfigurationProperties注解的Bean@RefreshScope的Bean`去完成刷新,完成刷新工作之后,下次我们再访问相应的对象时,就会拿到新的对象,获取到新的属性值,从而实现配置文件的自动。

2.6 总结

image.png
最后编辑于
?著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 214,172评论 6 493
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 91,346评论 3 389
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事?!?“怎么了?”我有些...
    开封第一讲书人阅读 159,788评论 0 349
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 57,299评论 1 288
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 66,409评论 6 386
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 50,467评论 1 292
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 39,476评论 3 412
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 38,262评论 0 269
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 44,699评论 1 307
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 36,994评论 2 328
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 39,167评论 1 343
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 34,827评论 4 337
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 40,499评论 3 322
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 31,149评论 0 21
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 32,387评论 1 267
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 47,028评论 2 365
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 44,055评论 2 352

推荐阅读更多精彩内容