Nacos 配置自动刷新

Nacos 配置自动刷新是指在 Nacos 中的配置文件变更后,应用程序(微服务)无需重启就可以感知。下面将介绍在 Spring Boot 和 Spring Cloud 项目中如何实现配置自动刷新。

Spring Boot

通过 @NacosValue 注解

@NacosValue 注解是 Nacos 提供的注解,它允许您动态地从 Nacos 中注入配置值。通过使用 @NacosValue,您可以轻松地检索和更新配置值,而无需重新启动应用程序。例如:

pom.xml 依赖

<dependency>
   <groupId>com.alibaba.boot</groupId>
   <artifactId>nacos-config-spring-boot-starter</artifactId>
   <version>0.2.7</version>
</dependency>

application.yml

server:
 port: 8080

spring:
 application:
   name: nacos_spring_boot_demo

# nacos相关配置
nacos:
 config:
   bootstrap:
     # 开启系统启动时预读取 nacos 的配置,用于满足 @Value 注入数据的场景
     enable: true
   # 配置所属命名空间的 id,此处我们配置名称为 dev 的 id,可以在命名空间列表查看 id 的值
   namespace: 8719efd1-94a6-49f7-9846-2debd66f6c0f
   # 配置所属分组
   group: DEFAULT_GROUP
   # 配置ID
   data-id: nacos_spring_boot_demo
   # 配置文件类型,对应 nacos 配置页面的配置格式,默认是 properties
   type: yaml
   # nacos 服务器地址
   server-addr: 127.0.0.1:8848
   username: nacos
   password: nacos
   # 开启自动刷新 nacos 配置
   # 注意,需要使用 @NacosValue 注解,并且 autoRefreshed 必须设置为 true
   auto-refresh: true
   # 针对配置项同名的情况,是否允许 nacos 的配置覆盖本地的配置
   remote-first: true

Demo1.java

package com.hxstrive.nacos;

import com.alibaba.nacos.api.config.annotation.NacosValue;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RestController;

/**
* 利用 @NacosValue 或 @Value 注入配置信息
* @author hxstrive.com
*/
@RestController
public class Demo1 {

   // 可以实现自动刷新
   @NacosValue(value = "${demo.title}", autoRefreshed = true)
   private String nacosValueTitle;

   // 不能自动刷新
   @Value("${demo.title}")
   private String title;

   @GetMapping("/demo1")
   public Demo1 demo1() {
       return this;
   }

   public String getNacosValueTitle() {
       return nacosValueTitle;
   }

   public String getTitle() {
       return title;
   }
}

通过 ConfigurableApplicationContext 实现

ConfigurableApplicationContext 是 Spring Framework 中的一个接口,它扩展了 ApplicationContext 接口,提供了一些额外的方法,用于配置和管理应用程序上下文的生命周期和属性。例如:

pom.xml 依赖

<!-- @ConfigurationProperties 需要 -->
<dependency>
   <groupId>org.springframework.boot</groupId>
   <artifactId>spring-boot-configuration-processor</artifactId>
   <optional>true</optional>
</dependency>

application.yml

同上面配置

Demo3.java

package com.hxstrive.nacos;

import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.ConfigurableApplicationContext;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RestController;

/**
* 获取配置,自动刷新
* @author hxstrive.com
*/
@RestController
public class Demo3 {

   @Autowired
   private ConfigurableApplicationContext applicationContext;

   @GetMapping("/demo3")
   public String demo3() {
       // 可以感知配置的变化,每次获取最新的配置
       return applicationContext.getEnvironment().getProperty("demo.title");
   }

}

Spring Cloud

通过 @RefreshScope 注解

@RefreshScope 是 Spring Cloud 中的一个注解,用于实现动态刷新配置的功能。当使用 @RefreshScope 注解标记一个 Bean 时,Spring Cloud 会自动将该 Bean 包装在一个代理对象中,并在代理对象被访问时检查是否需要刷新配置。例如:

pom.xml

<dependencyManagement>
   <dependencies>
       <dependency>
           <groupId>com.alibaba.cloud</groupId>
           <artifactId>spring-cloud-alibaba-dependencies</artifactId>
           <version>2.1.2.RELEASE</version>
           <type>pom</type>
           <scope>import</scope>
       </dependency>
       <!-- https://mvnrepository.com/artifact/org.springframework.cloud/spring-cloud-dependencies -->
       <dependency>
           <groupId>org.springframework.cloud</groupId>
           <artifactId>spring-cloud-dependencies</artifactId>
           <version>Greenwich.RELEASE</version>
           <type>pom</type>
           <scope>import</scope>
       </dependency>
       <!-- https://mvnrepository.com/artifact/org.springframework.boot/spring-boot-dependencies -->
       <dependency>
           <groupId>org.springframework.boot</groupId>
           <artifactId>spring-boot-dependencies</artifactId>
           <version>2.1.3.RELEASE</version>
           <type>pom</type>
           <scope>import</scope>
       </dependency>
   </dependencies>
</dependencyManagement>

<dependencies>
   <!-- Spring Boot Begin -->
   <dependency>
       <groupId>org.springframework.boot</groupId>
       <artifactId>spring-boot-starter-web</artifactId>
   </dependency>

   <dependency>
       <groupId>org.springframework.boot</groupId>
       <artifactId>spring-boot-starter-actuator</artifactId>
   </dependency>

   <!-- @ConfigurationProperties 需要 -->
   <dependency>
       <groupId>org.springframework.boot</groupId>
       <artifactId>spring-boot-configuration-processor</artifactId>
       <optional>true</optional>
   </dependency>

   <dependency>
       <groupId>org.springframework.boot</groupId>
       <artifactId>spring-boot-starter-test</artifactId>
       <scope>test</scope>
   </dependency>
   <!-- Spring Boot End -->

   <!-- Spring Cloud Begin -->
   <dependency>
       <groupId>com.alibaba.cloud</groupId>
       <artifactId>spring-cloud-starter-alibaba-nacos-config</artifactId>
   </dependency>
   <!-- Spring Cloud End -->
</dependencies>

application.yml

server:
 port: 8080

spring:
 application:
   # 应用名称,用来匹配 Nacos 中的配置集
   # 默认将根据下面指定的 spring.cloud.config.namespace + spring.cloud.config.group + spring.application.name + file-extension
   # 进行匹配,例如:当前应用将匹配
   # 8719efd1-94a6-49f7-9846-2debd66f6c0f 命名空间中 DEFAULT_GROUP 分组下
   # 名为 nacos_spring_cloud 且格式为 yaml 的配置集
   name: nacos_spring_cloud_demo
 cloud:
   nacos:
     config:
       # Nacos 服务地址
       server-addr: 127.0.0.1:8848
       # Nacos 配置文件扩展名
       file-extension: yaml
       # Nacos 命名空间ID
       namespace: 8719efd1-94a6-49f7-9846-2debd66f6c0f
       # Nacos 分组
       group: DEFAULT_GROUP
       # Nacos 登录账号
       username: nacos
       # Nacos 登录密码
       password: nacos

Demo1.java

package com.hxstrive.nacos;

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;

/**
* 通过 @RefreshScope 注解实现配置自动刷新
* @author hxstrive.com
*/
@RestController
@RefreshScope
public class Demo1 {

   @Value("${demo.title}")
   private String title;

   @GetMapping("/demo1")
   public String demo1() {
       return title;
   }

}

使用 @ConfigurationProperties 注解

@ConfigurationProperties 是一个 Spring Boot 注解,用于将配置文件中的属性值绑定到 Java 对象上。通过使用 @ConfigurationProperties 注解,可以方便地将配置文件中的属性值注入到应用程序中的相应属性中。注意,在 Spring Boot 项目中不能实现自动刷新,在 Spring Cloud 项目中可以实现自动刷新。例如:

pom.xml

同上

application.yml

同上

Demo2.java

package com.hxstrive.nacos;

import org.springframework.boot.context.properties.ConfigurationProperties;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RestController;

/**
* 使用 @ConfigurationProperties 注解实现配置自动加载
* @author hxstrive.com
*/
@RestController
@ConfigurationProperties(prefix = "demo")
public class Demo2 {

   private String title;

   @GetMapping("/demo2")
   public String demo2() {
       return title;
   }

   public void setTitle(String title) {
       this.title = title;
   }

}
说说我的看法
全部评论(
没有评论
关于
本网站专注于 Java、数据库(MySQL、Oracle)、Linux、软件架构及大数据等多领域技术知识分享。涵盖丰富的原创与精选技术文章,助力技术传播与交流。无论是技术新手渴望入门,还是资深开发者寻求进阶,这里都能为您提供深度见解与实用经验,让复杂编码变得轻松易懂,携手共赴技术提升新高度。如有侵权,请来信告知:hxstrive@outlook.com
公众号