【深入理解SpringCloud微服务】深入理解nacos配置中心(六)——spring-cloud-context关于配置刷新的公共逻辑

【深入理解SpringCloud微服务】深入理解nacos配置中心(六)——spring-cloud-context关于配置刷新的公共逻辑

我们在上一篇文章《客户端监听配置变更并刷新的源码分析》中最后说到,nacos客户端监听到配置变更通知后,会发布一个RefreshEvent事件,触发spring-cloud-context关于配置刷新的公共逻辑。但是由于它不是nacos实现的逻辑,我们没有对这段逻辑进行分析,本篇文章将会分析spring-cloud-context关于配置刷新的公共逻辑。

原理分析

spring-cloud-context会往Spring容器中注册一个监听器RefreshEventListener,这个监听器会监听并处理RefreshEvent事件。

在这里插入图片描述

RefreshEventListener监听到RefreshEvent事件后,会调用ContextRefresher的refresh()进行配置刷新的操作。

在这里插入图片描述

ContextRefresher的refresh()会做两件事情:

  1. 创建一个新的SpringApplication再跑一遍run()方法拿到最新的配置,覆盖到当前环境Environment中
  2. 销毁被@RefreshScope注解修饰的bean,等下一次调用到该bean时从容器中获取发现没有了,会重新创建一个,此时就会拿到最新的配置

在这里插入图片描述

首先解析第一件事情:创建一个新的SpringApplication再跑一遍run()方法。

SpringApplication的run()方法就是SpringBoot工程启动时的main方法执行的方法,这里创建一个新的SpringApplication,执行它的run()方法,就会得到一个新的ApplicationContext,里面的Environment中的配置都是最新的配置,拿到这个Environment就等于拿到了最新的配置。

也就是说这里就是为了加载到最新的配置,因此才新建一个新的SpringApplication并执行它的run()方法的,这是拿到最新配置最省事的做法。

在这里插入图片描述

然后解析第二件事情:销毁被@RefreshScope注解修饰的bean。

@RefreshScope注解修饰的bean的属性引用的配置都是会动态刷新的,也就是说如果我们更新了配置,那么它就会读到最新的配置。

如果让我们去实现这个功能,我们第一时间想到的是拿到最新的配置,重新给这些bean赋值。这么做确实是可以的,就是太麻烦了。

因此最好的做法就是把它们销毁,下次如果要用到这个bean,Spring发现没有,就会重新创建一个并初始化,由于当前Environment已经被覆盖了最新的配置,因此新创建的bean的属性引用到的配置值就是最新的。

在这里插入图片描述

带着对原理理解的认知,我们就可以去看源码了。

源码解析

RefreshEventListener#onApplicationEvent(ApplicationEvent)

spring-cloud-context的spring.factories文件指定了自动配置类RefreshAutoConfiguration,通过SpringBoot的自动装配机制,会自动加载并解析RefreshAutoConfiguration。

RefreshAutoConfiguration中通过@Bean注解注册了一个监听器RefreshEventListener。

在这里插入图片描述

RefreshEventListener的onApplicationEvent方法监听RefreshEvent事件并进行处理。

在这里插入图片描述

	public void onApplicationEvent(ApplicationEvent event) {
   
   
		...
			handle((RefreshEvent) event);
		...
	}

	public void handle(RefreshEvent event) {
   
   
		...
			// 调用ContextRefresher的refresh()方法进行配置刷新操作
			Set<String> keys = this.refresh.refresh();
			log.info("Refresh keys changed: " + keys);
		...
	}

RefreshEventListener的onApplicationEvent方法监听RefreshEvent事件后,会调用ContextRefresher的refresh()方法进行配置刷新操作。

在这里插入图片描述

这个ContextRefresher也是在RefreshAutoConfiguration中通过@Bean注册到Spring容器中的,并且会作为RefreshEventListener构造方法的参数。

在这里插入图片描述

ContextRefresher#refresh()

	public synchronized Set<String> refresh() {
   
   
		// 第一件事情:创建一个新的SpringApplication再跑一遍run()方法
		<
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值