无需重启服务,实时更新配置! 本文将深入探索Spring Boot中
@RefreshScope的神奇力量,让你的应用配置在运行时动态刷新,彻底告别服务重启的烦恼。
在传统Java应用中,修改配置文件后必须重启服务才能生效,这会导致:
Spring Boot的@RefreshScope完美解决了这些问题,实现配置热更新,让应用像乐高积木一样灵活重组!
|
1 2 3 4 5 6 |
graph TD A[修改配置文件] --> B[发送POST刷新请求] B --> C[/actuator/refresh 端点] C --> D[RefreshScope 刷新机制] D --> E[销毁旧Bean并创建新Bean] E --> F[新配置立即生效] |
@Value注解的值@RefreshScope标记的Bean|
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 |
<!-- pom.xml --> <dependencies> <!-- Spring Boot基础依赖 --> <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> <!-- 配置中心支持 --> <dependency> <groupId>org.springframework.cloud</groupId> <artifactId>spring-cloud-starter</artifactId> <version>3.1.3</version> </dependency> </dependencies> |
|
1 2 3 4 5 6 7 8 |
// 主应用类 @SpringBootApplication @EnableRefreshScope // 关键注解:开启配置刷新能力 public class DynamicConfigApp { public static void main(String[] args) { SpringApplication.run(DynamicConfigApp.class, args); } } |
|
1 2 3 4 5 6 7 8 9 10 11 12 13 14 |
# 应用基础配置 app: feature: enabled: true timeout: 5000 retry-count: 3 welcome-msg: "Hello, Dynamic Config!" # 暴露刷新端点(关键!) management: endpoints: web: exposure: include: refresh,health,info |
|
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 |
@Service @RefreshScope // 标记此Bean支持动态刷新 public class FeatureService { // 注入可刷新的配置项 @Value("${app.feature.enabled}") private boolean featureEnabled; @Value("${app.feature.timeout}") private int timeout; @Value("${app.feature.retry-count}") private int retryCount; @Value("${app.feature.welcome-msg}") private String welcomeMessage; public String getFeatureConfig() { return String.format(""" Feature Enabled: %s Timeout: %d ms Retry Count: %d Message: %s """, featureEnabled, timeout, retryCount, welcomeMessage); } } |
|
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 |
@RestController @RequestMapping("/config") public class ConfigController { private final FeatureService featureService; // 构造函数注入 public ConfigController(FeatureService featureService) { this.featureService = featureService; } @GetMapping public String getConfig() { return featureService.getFeatureConfig(); } } |
修改application.yml后,发送刷新请求:
|
1 |
curl -X POST http://localhost:8080/actuator/refresh |
响应示例(返回被修改的配置项):
|
1 |
["app.feature.timeout", "app.feature.welcome-msg"] |
|
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 |
// 伪代码:Spring如何实现动态刷新 public class RefreshScopeProxy implements ApplicationContextAware { private Object targetBean; @Override public Object invoke(Method method) { if (configChanged) { // 1. 销毁旧Bean context.destroyBean(targetBean); // 2. 重新创建Bean targetBean = context.getBean(beanName); } return method.invoke(targetBean, args); } } |
场景1:只刷新特定Bean的部分属性
|
1 2 3 4 5 6 7 8 9 10 |
@Component @RefreshScope public class PaymentService { // 只有带@Value的属性会刷新 @Value("${payment.timeout}") private int timeout; // 不会被刷新的属性 private final String apiVersion = "v1.0"; } |
场景2:组合配置类刷新
|
1 2 3 4 5 6 7 8 9 10 11 12 13 |
@Configuration @RefreshScope // 整个配置类可刷新 public class AppConfig { @Bean @RefreshScope public FeatureService featureService() { return new FeatureService(); } @Value("${app.theme}") private String theme; } |
|
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 |
management: endpoint: refresh: enabled: true endpoints: web: exposure: include: refresh base-path: /internal # 修改默认路径 path-mapping: refresh: secure-refresh # 端点重命名 # 添加安全认证 spring: security: user: name: admin password: $2a$10$NVM0n8ElaRgg7zWO1CxUdei7vWoQP91oGycgVNCY8GQEx.TGx.AaC |
方案1:Git Webhook自动刷新
方案2:配置中心联动(Nacos示例)
|
1 2 3 4 5 6 7 |
// bootstrap.yml spring: cloud: nacos: config: server-addr: localhost:8848 auto-refresh: true # 开启自动刷新 |
解决方案:
@RefreshScopelogging.level.org.springframework.cloud=DEBUG解决方案:
|
1 2 |
# 使用Spring Cloud Bus同步刷新 curl -X POST http://host:port/actuator/bus-refresh |
预防措施:
|
1 2 3 4 |
@PreDestroy public void cleanUp() { // 清理资源 } |
|
1 2 |
# 修改后立即生效 feature.new-checkout.enabled=true |
|
1 2 3 4 5 6 |
@RefreshScope public class LogConfig { @Value("${logging.level.root}") private String logLevel; // 动态应用新日志级别 } |
|
1 2 |
# 动态修改连接池配置 spring.datasource.hikari.maximum-pool-size=20 |
通过@RefreshScope,我们实现了:
✅ 零停机配置更新
✅ 即时生效的应用参数
✅ 更灵活的运维体验
✅ 资源利用最大化
最佳实践建议:
from:https://blog.csdn.net/renfusheng1993/article/details/149697314