springboot配置 之 nacos配置的动态监听刷新

在 Spring Boot 中监听 Nacos 配置的变化,可以通过 @RefreshScope@NacosConfigListener编程式监听 的方式实现。以下是详细方法:


动态监听的方式

1. 使用 @RefreshScope + @Value(适用于简单配置)

适用于动态刷新 @Value 注解的配置项。

步骤

  1. 添加依赖(确保已引入 Nacos Config Starter):

    <dependency>
        <groupId>com.alibaba.cloud</groupId>
        <artifactId>spring-cloud-starter-alibaba-nacos-config</artifactId>
        <version>${spring-cloud-alibaba.version}</version>
    </dependency>
    
  2. application.yml 中配置 Nacos

    spring:
      application:
        name: your-service-name
      cloud:
        nacos:
          config:
            server-addr: 127.0.0.1:8848
            file-extension: yaml # 配置格式(支持 properties/yaml)
    
  3. 在 Nacos 控制台创建配置

    • Data ID: your-service-name.yaml(与 spring.application.name 一致)
    • Group: DEFAULT_GROUP(默认)
    • 配置格式: YAML
    • 内容示例:
      config:
        key: "initial-value"
      
  4. 在代码中使用 @Value + @RefreshScope

    import org.springframework.beans.factory.annotation.Value;
    import org.springframework.cloud.context.config.annotation.RefreshScope;
    import org.springframework.web.bind.annotation.GetMapping;
    import org.springframework.web.bind.annotation.RestController;
    
    @RestController
    @RefreshScope // 允许动态刷新
    public class ConfigController {
    
        @Value("${config.key}")
        private String configKey;
    
        @GetMapping("/config")
        public String getConfig() {
            return configKey;
        }
    }
    
  5. 测试动态刷新

    • 修改 Nacos 控制台中的 config.key 值并发布。
    • 调用 /actuator/refresh(需暴露端点)或直接访问 /config 接口,观察值是否更新。

2. 使用 @NacosConfigListener(推荐)

适用于监听特定 dataIdgroupId 的配置变化,并执行自定义逻辑。

步骤

  1. 添加依赖(同上)。

  2. 编写监听器

    import com.alibaba.nacos.api.config.annotation.NacosConfigListener;
    import org.springframework.stereotype.Component;
    
    @Component
    public class NacosConfigListener {
    
        @NacosConfigListener(
            dataId = "your-service-name.yaml", // 监听的 Data ID
            groupId = "DEFAULT_GROUP",        // 监听的 Group
            type = ConfigType.YAML            // 配置类型(YAML/PROPERTIES)
        )
        public void onConfigChanged(String newConfig) {
            System.out.println("配置发生变化: " + newConfig);
            // 解析 YAML 并更新本地配置
            // 例如:使用 SnakeYAML 解析 newConfig
        }
    }
    
  3. 处理配置变更

    • newConfig 是变更后的完整配置内容(字符串)。
    • 可使用 SnakeYAMLJackson 解析 YAML/JSON。

3. 编程式监听(手动控制)

通过 ConfigService 直接监听配置变化。

步骤

  1. 注入 ConfigService

    import com.alibaba.nacos.api.config.ConfigService;
    import org.springframework.beans.factory.annotation.Autowired;
    import org.springframework.stereotype.Component;
    
    @Component
    public class ManualNacosListener {
    
        @Autowired
        private ConfigService configService;
    
        public void addListener() throws NacosException {
            configService.addListener(
                "your-service-name.yaml", 
                "DEFAULT_GROUP", 
                new Listener() {
                    @Override
                    public void receiveConfigInfo(String configInfo) {
                        System.out.println("配置变更: " + configInfo);
                    }
    
                    @Override
                    public Executor getExecutor() {
                        return null; // 使用默认线程池
                    }
                }
            );
        }
    }
    
  2. 在应用启动时注册监听

    import org.springframework.boot.ApplicationRunner;
    import org.springframework.stereotype.Component;
    
    @Component
    public class NacosListenerInitializer implements ApplicationRunner {
    
        @Autowired
        private ManualNacosListener manualNacosListener;
    
        @Override
        public void run(ApplicationArguments args) throws Exception {
            manualNacosListener.addListener();
        }
    }
    

4. 结合 @ConfigurationProperties 动态刷新

适用于绑定复杂配置对象。

步骤

  1. 定义配置类

    import org.springframework.boot.context.properties.ConfigurationProperties;
    import org.springframework.cloud.context.config.annotation.RefreshScope;
    import org.springframework.stereotype.Component;
    
    @Component
    @RefreshScope
    @ConfigurationProperties(prefix = "config")
    public class MyConfig {
        private String key;
        private int timeout;
    
        // Getter & Setter
        public String getKey() { return key; }
        public void setKey(String key) { this.key = key; }
        public int getTimeout() { return timeout; }
        public void setTimeout(int timeout) { this.timeout = timeout; }
    }
    
  2. 在 Nacos 中配置

    config:
      key: "dynamic-value"
      timeout: 5000
    
  3. 使用配置

    @RestController
    public class ConfigController {
    
        @Autowired
        private MyConfig myConfig;
    
        @GetMapping("/config")
        public MyConfig getConfig() {
            return myConfig; // 自动刷新
        }
    }
    

5. 暴露 actuator/refresh 端点(可选)

如果使用 @RefreshScope,需暴露刷新端点:

management:
  endpoints:
    web:
      exposure:
        include: refresh,health,info

然后手动调用 /actuator/refresh 触发刷新(或通过消息总线自动触发)。


总结

方式 适用场景 特点
@RefreshScope + @Value 简单配置项 需手动调用 /actuator/refresh
@NacosConfigListener 自定义监听逻辑 直接监听 dataId 变化
编程式 ConfigService 完全手动控制 灵活但代码复杂
@ConfigurationProperties 复杂配置对象 支持结构化配置

推荐

  • 简单场景用 @RefreshScope + @Value
  • 需要精细控制时用 @NacosConfigListener
  • 复杂对象用 @ConfigurationProperties

ConfigService使用

在 Spring Boot 中,ConfigService 不会自动注入,因为它不是 Spring 容器默认管理的 Bean。你需要手动配置它,或者通过 Nacos 提供的 NacosConfigManager 来获取 ConfigService 实例。


解决方法

1. 通过 @Bean 手动注册 ConfigService

在 Spring Boot 中,可以通过 NacosConfigPropertiesNacosConfigManager 来获取 ConfigService,然后手动将其注册为 Bean。

步骤

  1. 添加依赖(确保已引入 Nacos Config Starter):

    <dependency>
        <groupId>com.alibaba.cloud</groupId>
        <artifactId>spring-cloud-starter-alibaba-nacos-config</artifactId>
        <version>${spring-cloud-alibaba.version}</version>
    </dependency>
    
  2. 配置 ConfigService Bean

    import com.alibaba.nacos.api.config.ConfigService;
    import org.springframework.beans.factory.annotation.Autowired;
    import org.springframework.context.annotation.Bean;
    import org.springframework.context.annotation.Configuration;
    import com.alibaba.cloud.nacos.NacosConfigProperties;
    
    @Configuration
    public class NacosConfig {
    
        @Autowired
        private NacosConfigProperties nacosConfigProperties;
    
        @Bean
        public ConfigService configService() throws Exception {
            return nacosConfigProperties.configServiceInstance();
        }
    }
    
  3. 在代码中注入 ConfigService

    import com.alibaba.nacos.api.config.ConfigService;
    import org.springframework.beans.factory.annotation.Autowired;
    import org.springframework.stereotype.Component;
    
    @Component
    public class AutoDelayJob {
    
        @Autowired
        private ConfigService configService; // 现在可以正常注入
    
        public void someMethod() {
            try {
                String config = configService.getConfig("dataId", "group", 5000);
                System.out.println("配置内容: " + config);
            } catch (Exception e) {
                e.printStackTrace();
            }
        }
    }
    

2. 直接使用 NacosConfigManager(推荐)

Spring Cloud Alibaba Nacos 提供了 NacosConfigManager,它可以更方便地获取 ConfigService

步骤

  1. 注入 NacosConfigManager
    import com.alibaba.cloud.nacos.NacosConfigManager;
    import org.springframework.beans.factory.annotation.Autowired;
    import org.springframework.stereotype.Component;
    
    @Component
    public class AutoDelayJob {
    
        @Autowired
        private NacosConfigManager nacosConfigManager; // 直接注入
    
        public void someMethod() {
            try {
                ConfigService configService = nacosConfigManager.getConfigService();
                String config = configService.getConfig("dataId", "group", 5000);
                System.out.println("配置内容: " + config);
            } catch (Exception e) {
                e.printStackTrace();
            }
        }
    }
    

3. 检查 Nacos 配置是否正确

如果仍然报错,请检查:

  1. application.yml 是否配置了 Nacos
    spring:
      cloud:
        nacos:
          config:
            server-addr: 127.0.0.1:8848
            namespace: your-namespace-id # 可选
            group: DEFAULT_GROUP        # 默认组
            file-extension: yaml        # 配置格式
    
  2. 是否引入了 spring-cloud-starter-alibaba-nacos-config
  3. Nacos 服务器是否可访问(检查 server-addr 是否正确)。

总结

方法 适用场景 优点
手动注册 ConfigService 需要直接控制 ConfigService 实例 灵活,但需要额外配置
使用 NacosConfigManager 推荐方式 简洁,Spring Cloud Alibaba 官方推荐
检查 Nacos 配置 基础问题排查 确保 Nacos 连接正常

推荐

  • 优先使用 NacosConfigManager,因为它已经由 Spring Cloud Alibaba 管理,无需手动注册。
  • 如果遇到 ConfigService 注入失败,检查 Nacos 配置是否正确,并确保依赖已引入。🚀
posted @ 2025-09-17 13:21  蓝迷梦  阅读(469)  评论(0)    收藏  举报