Spring Cloud 热更新机制原理学习

本文探讨了Spring Cloud的热更新机制,包括通过ContextRefresher手动或通过Spring Cloud Bus自动刷新配置。主要涉及@ConfigurationProperties的重绑定和@RefreshScope的缓存刷新,以及热更新可能导致的配置不一致性问题。文章还提到了监听EnvironmentChangeEvent来实现更原子性的配置更新策略。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

博主在调研 Spring Cloud Config 跟 Apollo 配置中心的时候,对其中的热更新机制比较有兴趣,并阅读了相关的源码,在这里进行记录,方便以后查看。

调研时使用的 Spring Boot 跟 Spring Cloud 的版本:

    <dependencyManagement>
        <dependencies>
            <dependency>
                <groupId>org.springframework.boot</groupId>
                <artifactId>spring-boot-dependencies</artifactId>
                <version>1.5.21.RELEASE</version>
                <type>pom</type>
                <scope>import</scope>
            </dependency>
            <dependency>
                <groupId>org.springframework.cloud</groupId>
                <artifactId>spring-cloud-dependencies</artifactId>
                <version>Edgware.SR6</version>
                <type>pom</type>
                <scope>import</scope>
            </dependency>
        </dependencies>
    </dependencyManagement>

知识背景

Spring Cloud Config 提供了一套配置中心,结合 Spring Cloud Bus 可实现一套配置的自动热更新。其实通过阅读源码,无论是 Spring Cloud Config 的手动刷新,还是通过 Spring Cloud Bus 通知进行自动刷新配置,最终底层都是使用了Spring Cloud 提供的热更新机制,换句话说,其实无需使用配置中心,通过手动修改配置文件,触发refresh 端点也可以触发热更新

Spring Cloud 热更新机制,支持热更新的配置有三类,分别是:@ConfigurationProperties 注入的配置类日志相关@RefreshScope 注解的类。而对于这三类配置,Spring Cloud 提供了两种更新策略,对于前两类,采用类的重新绑定策略进行更新,而最后的 @RefreshScope,采用了延迟加载跟缓存刷新的策略。下面将讲解具体的实现方式。

源码阅读

热更新机制的入口为调用ContextRefresher类的refresh方法,代码如下:

	public synchronized Set<String> refresh() {
   
   
    	// 1. 获取当前配置源信息 
		Map<String, Object> before = extract(
				this.context.getEnvironment().getPropertySources());
		// 2. 加载配置
    	addConfigFilesToEnvironment();
		// 3. 获取修改了配置值的kd
    	Set<String> keys = changes(before,
				extract(this.context.getEnvironment().getPropertySources())).keySet();
		// 4. 发布变更事件
    	this.context.publishEvent(new EnvironmentChangeEvent(context, keys));
		// 5. 刷新@refreshScope类
    	this.scope.refreshAll();
		return keys;
	}

下面对上面的代码进行解读:

1. 获取当前属性源信息

这里获取环境的所有属性源的信息,但从中去除标准属性源:

	private Map<String, Object> extract(MutablePropertySources propertySources) {
   
   
		Map<String, Object> result = new HashMap<String, Object>();
		List<PropertySource<?>> sources = new ArrayList<PropertySource<?>>
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值