SpringBoot不重启服务的情况下刷新配置文件
-
所需要的依赖
<dependency> <groupId>org.springframework.cloud</groupId> <artifactId>spring-cloud-starter-config</artifactId> </dependency> <!--监控+refresh配置--> <dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-actuator</artifactId> </dependency>
-
测试controller
package com.dist.ytgz.approve.controller; import io.swagger.v3.oas.annotations.tags.Tag; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.beans.factory.annotation.Value; import org.springframework.cloud.context.config.annotation.RefreshScope; import org.springframework.cloud.context.refresh.ContextRefresher; import org.springframework.web.bind.annotation.*; /** * TODO * * @author <a href="mailto:zhangxiao@dist.com.cn">Zhang Xiao</a> * @since */ @RefreshScope @Tag(name = "test") @RestController @RequestMapping("/test") public class TestController { @Autowired private ContextRefresher contextRefresher; @Value("${test}") private String t; /** * 刷新配置文件, 每个需要用到配置文件的类, 都需要加@RefreshScope, 所以放我们写配置类@Configuration/@ConfigurationProperties等...最好吧@RefreshScope加上 * @return */ @GetMapping("/refresh") public String refresh() { new Thread(() -> contextRefresher.refresh()).start(); return "success"; } @GetMapping("/test") public String test() { return this.t; } }
-
启动类正常启动就行不需要加其他任何的注解
-
编译后的文件是1
-
调用test方法得到的结果
-
把编译后的配置文件test修改为2, 然后调用我们refresh方法, 然后再次调用test方法
-
总结
主要是refreshEnvironment它是比较前一个版本的配置文件和修改后的配置文件的却别, 把修改过得key当放入到对应的环境变量修改事件中, 放到对应的上下文, 返回对应的key, 刷新标注了RefreshScope注解的bean, 上下文会触发对应的事件进行修改。
ContextRefresher 是用来刷新容器中标记了@RefreshScope Bean的类,它的refresh()方法可以实现这一功能。大概流程就是刷新当前容器的environment,删除掉Scope中的实例,然后在获取实例时从小建立bean,这时候新的enviroment已经生成,就拿到了最新的配置