apollo官网-配置动态刷新

项目中在使用apollo作为配置中心。现在有需求:配置项发生变化,对应的配置需动态刷新。

背景

配置类:

@Component
@Data
@RefreshScope
@ConfigurationProperties(prefix = "home.setting.dict")
public class HomeSettingProperties {
    
    @ApiModelProperty("金刚区")
    private String kingKongSetting;
    
    //...
}

主要是对 HomeSettingProperties 中的属性 kingKongSetting 进行动态更新

实现方式

在项目使用的是结合 RefreshScope 的方式实现动态刷新,需要注意的是,在配置类中需要配置注解 @RefreshScope@ConfigurationProperties

监听类:

import com.ctrip.framework.apollo.model.ConfigChange;
import com.ctrip.framework.apollo.model.ConfigChangeEvent;
import com.ctrip.framework.apollo.spring.annotation.ApolloConfigChangeListener;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.cloud.context.scope.refresh.RefreshScope;
import org.springframework.context.annotation.Configuration;

@Configuration
@Slf4j
public class ApolloConfig {

    @Autowired
    private RefreshScope refreshScope;

    @ApolloConfigChangeListener
    public void changeHandler(ConfigChangeEvent changeEvent) {
        for (String key : changeEvent.changedKeys()) {
            ConfigChange change = changeEvent.getChange(key);
            log.info("配置发生变化 {}", change.toString());
            refresh(key);
        }
    }

    /**
     * 刷新配置
     *
     * @param key
     */
    public void refresh(String key) {

        if (key.contains("home.setting")) {
            log.info("before refresh:{}",homeSettingProperties);
            refreshScope.refresh("homeSettingProperties");
            log.info("after refresh:{}",homeSettingProperties);
        }
    }
}

修改下配置,可以看到配置生效了

'[2022-02-09 16:53:56.860] 配置发生变化 ConfigChange{namespace='application', propertyName='home.setting.kingKongSetting', oldValue='123', newValue='456', changeType=MODIFIED}
[2022-02-09 16:53:56.861] [Apollo-Config-1] [INFO ] before refresh: kingKongSetting=123
[2022-02-09 16:53:56.862] [Apollo-Config-1] [INFO ] after refresh:kingKongSetting=456

原理

@RefreshScope 标注的类的scope为 refresh

当调用 refreshScope.refresh 方法的时候,首先销毁 scope 为 refresh 的bean实例,然后发出 RefreshScopeRefreshedEvent 事件,通知spring容器重新创建bean,获取新的配置。具体可以参考这个文章

Logo

为开发者提供学习成长、分享交流、生态实践、资源工具等服务,帮助开发者快速成长。

更多推荐