1. 创建一个 Spring Boot 工程
2. pom 文件加入 Nacos 依赖
<dependency>
<groupId>com.alibaba.cloud</groupId>
<artifactId>spring-cloud-starter-alibaba-nacos-config</artifactId>
<version>2.1.1.RELEASE</version>
</dependency>
3. 在 bootstrap.yml(本次示例配置文件选择 yaml 文件) 中配置 Nacos server 的地址和应用名
spring:
application:
name: nacos-demo-springcloud
cloud:
nacos:
config:
server-addr: 127.0.0.1:8848
file-extension: yml
说明:之所以需要配置 spring.application.name
,是因为它是构成 Nacos 配置管理 dataId 字段的一部分。
在 Nacos Spring Cloud 中,dataId 的完整格式如下:
${prefix}-${spring.profile.active}.${file-extension}
prefix 默认为 spring.application.name
的值,也可以通过配置项 spring.cloud.nacos.config.prefix
来配置。
spring.profile.active
即为当前环境对应的 profile,详情可以参考 Spring Boot 文档。 注意:当 spring.profile.active
为空时,对应的连接符 - 也将不存在,dataId 的拼接格式变成
${prefix}.${file-extension}
file-exetension 为配置内容的数据格式,可以通过配置项 spring.cloud.nacos.config.file-extension
来配置。目前只支持 properties 和 yaml 类型。
4. 通过 Spring Cloud 原生注解 @RefreshScope 实现配置自动更新
@RestController
@RequestMapping("/demo")
@RefreshScope
public class DemoController {
@Value("${test.name}")
private String name;
@Value("${test.name2}")
private String name2;
@RequestMapping("/name")
public String getName() {
return this.name;
}
@RequestMapping("/name2")
public String getName2() {
return this.name2;
}
}
5. 设置配置
登录到 Nacos 新建配置,Data ID 设置为 nacos-demo-springcloud.yml
,添加 2个配置项
test:
name: zhangsan
name2: lisi
6. 启动应用进行验证
首先能获取到配置项的值
访问 http://localhost:8080/demo/name 值为 zhangsan
访问 http://localhost:8080/demo/name2 值为 lisi
在 Nacos 页面修改配置项的值为
test:
name: zhangsansan
name2: lisisi
访问 http://localhost:8080/demo/name 值为 zhangsansan
访问 http://localhost:8080/demo/name2 值为 lisisi
验证值已经更新。
7. 验证对@ConfigurationProperties注解的支持
@ConfigurationProperties
的基本用法非常简单(详细介绍请见参考文档[2]):为每个要捕获的外部属性提供一个带有字段的类。
有以下几点需要注意:
- 前缀定义了哪些外部属性将绑定到类的字段上
- 根据 Spring Boot 宽松的绑定规则,类的属性名称必须与外部属性的名称匹配
- 我们可以简单地用一个值初始化一个字段来定义一个默认值
- 类本身可以是包私有的
- 类的字段必须有公共 setter 方法
创建一个类 User
@Data
public class User {
private Integer id;
private String name;
private Integer age;
}
定义 Bean,属性从配置中获取,前缀为 "user"
@Configuration
public class DemoConfig {
@Bean
@ConfigurationProperties(prefix = "user")
public User getUser() {
return new User();
}
}
在配置中心添加配置
user:
id: 1
name: wangwu
age: 25
Controller 添加代码
@Autowired
private User user;
@RequestMapping("/user")
public User getUser() {
return user;
}
访问 http://localhost:8080/demo/user 返回值 {"id":1,"name":"wangwu","age":25}
在配置中心改动配置为
user:
id: 1
name: zhaoliu
age: 26
访问 http://localhost:8080/demo/user 返回值 {"id":1,"name":"zhaoliu","age":26}
已经更新。
请注意 DemoConfig 配置类上并没有加注解 @RefreshScope
,但是 Bean user 属性的值也能更新。原因请见[3]的回答,这里转述如下:
原因是 spring-cloud 默认又新增了 ConfigurationPropertiesRebinder
类,它监听了EnvironmentChangeEvent 事件,它在发生 EnvironmentChange 事件后,会重新构造原来的加了
@ConfigurationProperties 注解的 Bean 对象。这个是 Spring Cloud 的默认实现。
/**
* Listens for {@link EnvironmentChangeEvent} and rebinds beans that were bound to the
* {@link Environment} using {@link ConfigurationProperties
* <code>@ConfigurationProperties</code>}. When these beans are re-bound and
* re-initialized, the changes are available immediately to any component that is using
* the <code>@ConfigurationProperties</code> bean.
*
* @see RefreshScope for a deeper and optionally more focused refresh of bean components.
* @author Dave Syer
*
*/
spring-cloud-starter-alibaba-nacos-config 依赖了 spring-cloud-context ,这里面包含了 ConfigurationPropertiesRebinder 类。这样就能解释通了。
参考文档
[1] https://nacos.io/zh-cn/docs/quick-start-spring-cloud.html
[2] https://blog.csdn.net/yusimiao/article/details/97622666
[3] https://www.oschina.net/question/867417_2268285