SpringBoot Nacos 动态配置延时生效方案

1.关闭配置文件的自动刷新

spring.cloud.nacos.config.refreshEnabled设为false,关闭配置自动刷新

2.添加nacos配置监听器,利用ContextRefresher刷新配置文件

读取配置文件的 effectAfter值,延时指定时间,利用 ContextRefresher刷新配置文件

package com.wangxin.demo.springboottdd.config;

import cn.hutool.core.thread.ThreadUtil;
import com.alibaba.cloud.nacos.NacosConfigManager;
import com.alibaba.cloud.nacos.NacosConfigProperties;
import com.alibaba.nacos.api.config.listener.Listener;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.ApplicationArguments;
import org.springframework.boot.ApplicationRunner;
import org.springframework.cloud.context.refresh.ContextRefresher;
import org.springframework.core.env.Environment;
import org.springframework.stereotype.Component;

import java.io.IOException;
import java.io.StringReader;
import java.util.Properties;
import java.util.concurrent.Executor;
import java.util.concurrent.TimeUnit;

/**
 * @Author: 我若为王
 * @Description: nacos配置延时生效
 * @Date: 2022/11/12 14:44
 * @Version: 1.0
 */
@Component
@Slf4j
public class ConfigRefreshRunner implements ApplicationRunner {


    @Autowired
    private NacosConfigProperties nacosConfigProperties;

    @Autowired
    private Environment env;

    @Autowired
    private ContextRefresher contextRefresher;

    @Override
    public void run(ApplicationArguments args) throws Exception {

        String conf = nacosConfigProperties.getPrefix() + "-" + env.getProperty("spring.profiles.active") + "." + nacosConfigProperties.getFileExtension();
        new NacosConfigManager(nacosConfigProperties).getConfigService().addListener(
                conf, nacosConfigProperties.getGroup(), new Listener() {
                    @Override
                    public void receiveConfigInfo(String configInfo) {
                        Properties properties = new Properties();
                        try {
                            properties.load(new StringReader(configInfo));
                        } catch (IOException e) {
                            e.printStackTrace();
                        }
                        Long effectAfter = Long.valueOf(properties.getProperty("effectAfter", "0"));
                        log.info("配置已变更,{}秒后生效", effectAfter);
                        ThreadUtil.sleep(effectAfter, TimeUnit.SECONDS);
                        contextRefresher.refresh();
                        log.info("配置已刷新");
                    }

                    @Override
                    public Executor getExecutor() {
                        return null;
                    }
                });
    }
}

示例配置

# 延时生效秒数
effectAfter: 10
server:
  # 端口号
  port: 20002
test: ttt
spring:
  aop:
    proxy-target-class: true  # AOP 打开
  main:
    allow-bean-definition-overriding: true