springboot配置 之 nacos配置的动态监听刷新
在 Spring Boot 中监听 Nacos 配置的变化,可以通过 @RefreshScope、@NacosConfigListener 或 编程式监听 的方式实现。以下是详细方法:
动态监听的方式
1. 使用 @RefreshScope + @Value(适用于简单配置)
适用于动态刷新 @Value 注解的配置项。
步骤
-
添加依赖(确保已引入 Nacos Config Starter):
<dependency> <groupId>com.alibaba.cloud</groupId> <artifactId>spring-cloud-starter-alibaba-nacos-config</artifactId> <version>${spring-cloud-alibaba.version}</version> </dependency> -
在
application.yml中配置 Nacos:spring: application: name: your-service-name cloud: nacos: config: server-addr: 127.0.0.1:8848 file-extension: yaml # 配置格式(支持 properties/yaml) -
在 Nacos 控制台创建配置:
- Data ID:
your-service-name.yaml(与spring.application.name一致) - Group:
DEFAULT_GROUP(默认) - 配置格式: YAML
- 内容示例:
config: key: "initial-value"
- Data ID:
-
在代码中使用
@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; } } -
测试动态刷新:
- 修改 Nacos 控制台中的
config.key值并发布。 - 调用
/actuator/refresh(需暴露端点)或直接访问/config接口,观察值是否更新。
- 修改 Nacos 控制台中的
2. 使用 @NacosConfigListener(推荐)
适用于监听特定 dataId 或 groupId 的配置变化,并执行自定义逻辑。
步骤
-
添加依赖(同上)。
-
编写监听器:
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 } } -
处理配置变更:
newConfig是变更后的完整配置内容(字符串)。- 可使用
SnakeYAML或Jackson解析 YAML/JSON。
3. 编程式监听(手动控制)
通过 ConfigService 直接监听配置变化。
步骤
-
注入
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; // 使用默认线程池 } } ); } } -
在应用启动时注册监听:
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 动态刷新
适用于绑定复杂配置对象。
步骤
-
定义配置类:
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; } } -
在 Nacos 中配置:
config: key: "dynamic-value" timeout: 5000 -
使用配置:
@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 中,可以通过 NacosConfigProperties 和 NacosConfigManager 来获取 ConfigService,然后手动将其注册为 Bean。
步骤
-
添加依赖(确保已引入 Nacos Config Starter):
<dependency> <groupId>com.alibaba.cloud</groupId> <artifactId>spring-cloud-starter-alibaba-nacos-config</artifactId> <version>${spring-cloud-alibaba.version}</version> </dependency> -
配置
ConfigServiceBean: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(); } } -
在代码中注入
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。
步骤
- 注入
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 配置是否正确
如果仍然报错,请检查:
application.yml是否配置了 Nacos:spring: cloud: nacos: config: server-addr: 127.0.0.1:8848 namespace: your-namespace-id # 可选 group: DEFAULT_GROUP # 默认组 file-extension: yaml # 配置格式- 是否引入了
spring-cloud-starter-alibaba-nacos-config。 - Nacos 服务器是否可访问(检查
server-addr是否正确)。
总结
| 方法 | 适用场景 | 优点 |
|---|---|---|
手动注册 ConfigService |
需要直接控制 ConfigService 实例 |
灵活,但需要额外配置 |
使用 NacosConfigManager |
推荐方式 | 简洁,Spring Cloud Alibaba 官方推荐 |
| 检查 Nacos 配置 | 基础问题排查 | 确保 Nacos 连接正常 |
推荐:
- 优先使用
NacosConfigManager,因为它已经由 Spring Cloud Alibaba 管理,无需手动注册。 - 如果遇到
ConfigService注入失败,检查 Nacos 配置是否正确,并确保依赖已引入。🚀
本文来自博客园,作者:蓝迷梦,转载请注明原文链接:https://www.cnblogs.com/hewei-blogs/articles/19096626

浙公网安备 33010602011771号