简介
本文手写组件,动态更新SpringBoot里@Value的值(无需重启服务)。
不是可以用@RefreshScope吗?为什么要手写组件?
原因是:@RefreshScope是有缺陷的,很多时候会失效。
动态更新配置的方法
动态更新配置属性有四种方式:
- @RefreshScope
- 详见:此文
- 用类表示配置。
- 详见:此文
- ApplicationContext
- 方法:ApplicationContextHolder.getContext().getEnvironment().getRequiredProperty(key);
- ApplicationContextHolder见:SpringBoot-静态获得Bean的工具类 – 自学精灵
- 本文组件。
这四种方式的对比:
比较项 | @RefreshScope | 用类表示配置 | ApplicationContext | 本文组件 |
启动时检查空值 | 是 (没配置会报错,能及时发现问题) | 否 (没配置不报错,无法及时发现问题) | 否 | 是 |
是否有失效的情况 | 是(详见: 这里) | 否 | 否 | 否 |
易用性 | ☆☆☆☆☆ | ☆☆☆ | ☆☆ | ☆☆☆☆☆ |
从上边可以发现,本文组件是最完美的!
结果展示
Controller代码
package com.knife.example.business.product.controller; import io.swagger.annotations.Api; import io.swagger.annotations.ApiOperation; import org.springframework.beans.factory.annotation.Value; import org.springframework.web.bind.annotation.GetMapping; import org.springframework.web.bind.annotation.RequestMapping; import org.springframework.web.bind.annotation.RestController; @Api(tags = "商品") @RestController @RequestMapping("product") public class ProductController { @Value("${key1:aa}") private String key1; @ApiOperation("测试") @GetMapping("detail") public String detail() { return key1; } }
测试
访问:http://localhost:8080/doc.html
修改Nacos,将key1改为bb,不重启应用。
再次请求:(可见,已经自动更新啦)
实现方案
第一步:项目在启动时,将带有@Value注解的bean记录下来。
第二步:在配置修改时,监听配置修改这个事件,通过反射将bean相应的字段给修改掉。
代码
下载源码
此隐藏内容仅限VIP查看升级VIP
代码结构
上边红框内的是核心代码。
此内容仅限VIP查看,请先登录
请先
!