Spring Cloud @RefreshScope和@EventListener实现Nacos配置更新监听

问题描述

使用@RefreshScope会刷新在Sprign IOC中所有Bean中使用@Value的值,但是在配置类中使用方法去配置的其他类参数并不会改变,例如

@Slf4j
@Configuration
@RefreshScope
public class SentinelConfig {
    @Bean
    public ZuulFilter sentinelZuulPreFilter() {
        return new SentinelZuulPreFilter();
    }

    @Bean
    public ZuulFilter sentinelZuulPostFilter() {
        return new SentinelZuulPostFilter();
    }

    @Bean
    public ZuulFilter sentinelZuulErrorFilter() {
        return new SentinelZuulErrorFilter();
    }

    @PostConstruct
    public void init() {
        ZuulBlockFallbackManager.registerProvider(new MyBlockFallbackProvider());
        Config config = ConfigService.getAppConfig();
        //Nacos后台配置更新,flowRules并不会改变,需要手动loadRules
        String flowRulesJson = config.getProperty("sentinel.flowRules",
                "[{\"burst\":0,\"controlBehavior\":0,\"count\":3.0,\"grade\":1,\"intervalSec\":1,\"maxQueueingTimeoutMs\":500,\"resource\":\"appblog-service\",\"resourceMode\":1}]");
        Set<GatewayFlowRule> flowRules = JSON.parseObject(flowRulesJson, new TypeReference<Set<GatewayFlowRule>>(){});
        GatewayRuleManager.loadRules(flowRules);
    }
}

解决方案

//使用此方法监听事件
@EventListener
public void envListener(EnvironmentChangeEvent event) {

}
@Slf4j
@Configuration
@RefreshScope
public class SentinelConfig {
    @Value("${sentinel.flowRules:[{\"burst\":0,\"controlBehavior\":0,\"count\":3.0,\"grade\":1,\"intervalSec\":1,\"maxQueueingTimeoutMs\":500,\"resource\":\"appblog-service\",\"resourceMode\":1}]}")
    private String flowRulesJson;

    @Bean
    public ZuulFilter sentinelZuulPreFilter() {
        return new SentinelZuulPreFilter();
    }

    @Bean
    public ZuulFilter sentinelZuulPostFilter() {
        return new SentinelZuulPostFilter();
    }

    @Bean
    public ZuulFilter sentinelZuulErrorFilter() {
        return new SentinelZuulErrorFilter();
    }

    @PostConstruct
    public void init() {
        ZuulBlockFallbackManager.registerProvider(new MyBlockFallbackProvider());
        Config config = ConfigService.getAppConfig();
        String flowRulesJson = config.getProperty("sentinel.flowRules",
                "[{\"burst\":0,\"controlBehavior\":0,\"count\":3.0,\"grade\":1,\"intervalSec\":1,\"maxQueueingTimeoutMs\":500,\"resource\":\"appblog-service\",\"resourceMode\":1}]");
        Set<GatewayFlowRule> flowRules = JSON.parseObject(flowRulesJson, new TypeReference<Set<GatewayFlowRule>>(){});
        GatewayRuleManager.loadRules(flowRules);
    }

    @EventListener
    public void envChangeListener(EnvironmentChangeEvent event) {
        log.info("Sentinel配置刷新");
        log.info(flowRulesJson);
        Set<GatewayFlowRule> flowRules = JSON.parseObject(flowRulesJson, new TypeReference<Set<GatewayFlowRule>>(){});
        GatewayRuleManager.loadRules(flowRules);
    }
}

原因分析

在调用刷新方法是会产生一个EnvironmentChangeEvent事件。进入ContextRefresher源码,看下refresh接口;

public synchronized Set<String> refresh() {
    Map<String, Object> before = extract(
            this.context.getEnvironment().getPropertySources());
    addConfigFilesToEnvironment();
    Set<String> keys = changes(before,
            extract(this.context.getEnvironment().getPropertySources())).keySet();
    // 注意这一行,抛出了一个变更事件
    this.context.publishEvent(new EnvironmentChangeEvent(context, keys));
    this.scope.refreshAll();
    return keys;
}

版权声明:
作者:Joe.Ye
链接:https://www.appblog.cn/index.php/2023/03/24/spring-cloud-refreshscope-and-eventlistener-implement-nacos-configuration-update-listening/
来源:APP全栈技术分享
文章版权归作者所有,未经允许请勿转载。

THE END
分享
二维码
打赏
海报
Spring Cloud @RefreshScope和@EventListener实现Nacos配置更新监听
问题描述 使用@RefreshScope会刷新在Sprign IOC中所有Bean中使用@Value的值,但是在配置类中使用方法去配置的其他类参数并不会改变,例如 @Slf4j @Configurat……
<<上一篇
下一篇>>
文章目录
关闭
目 录