• SpringBoot/SpringCloud: 应用配置项热加载与动态刷新


    springboot的配置通常是在以下文件中进行配置,在打包时就涵盖,或者在发布时指定外部配置文件

    • application.properties
    • application.yaml
    • application-{env}.properties
    • application-{env}.yaml

    通常一旦程序发布就不能修改配置,那有什么办法能够修改这上下文里的参数呢?
    以下方法涉及:

    • SpringBoot SpringCloud
    • 动态代理
    • 类加载
    • ContextRefresher.refresh()上下文刷新

    以下测试版本说明:

    • springcloud: 4.0.4
    • springboot: 3.1.0

    1、从actuator端点刷新应用属性

    主要用 SpringCloud 的上下文参数刷新的功能,接口 /actuator/refresh 的端点,实现应用属性的实时刷新。

    1.1 @ConfigurationProperties + /actuator/refresh

    1. 引入springboot框架
    2. 引入 springcloud 依赖,springboot-actuator 依赖,开启 refresh 端口

    application.yaml:

    server:
      port: 8080
    spring:
      application:
        name: springboot-config-refresh
    management:
      endpoints:
        web:
          exposure:
            include: refresh
    demo:
      message: files
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12

    pom.xml:

     <dependencies>
            <dependency>
                <groupId>org.springframework.bootgroupId>
                <artifactId>spring-boot-starter-webartifactId>
            dependency>
            <dependency>
                <groupId>org.springframework.cloudgroupId>
                <artifactId>spring-cloud-starterartifactId>
                <version>${spring-cloud.version}version>
            dependency>
            <dependency>
                <groupId>org.springframework.bootgroupId>
                <artifactId>spring-boot-starter-actuatorartifactId>
            dependency>
            <dependency>
                <groupId>org.projectlombokgroupId>
                <artifactId>lombokartifactId>
                <version>1.18.22version>
            dependency>
        dependencies>
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    1. 书写配置类 MyConfig ,结合 @ConfigurationProperties 这个注解是扫描生效的重点

    MyConfig.class

    @Data
    @Configuration
    @ConfigurationProperties(prefix = "demo")
    public class MyConfig {
    
        private String message ="default message";
    
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    1. 书写值查询的接口进行验证
    @RestController
    @RequestMapping
    public class ValueController {
        @Autowired
        private MyConfig myConfig;
    
        @GetMapping
        public String value(){
         return myConfig.getMessage();
        }
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    1. 请求API

    请求API获取初始配置

    curl --location --request GET '127.0.0.1:8080/'
    
    files
    
    • 1
    • 2
    • 3
    • war包部署或本地测试,可以修改class下配置文件application.yaml
    • jar包部署,需要启动时指定外部的文件,--spring.config.location=/Users/chenzy/application.yaml,此时修改外部文件保存即可
    server:
      port: 8080
    spring:
      application:
        name: springboot-config-refresh
    management:
      endpoints:
        web:
          exposure:
            include: refresh
      endpoint:
        refresh:
          enabled: true
    demo:
      message: newfiles
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15

    请求 /actuator/refresh 触发旧bean的销毁,并返回修改项

    curl --location --request POST '127.0.0.1:8080/actuator/refresh' \
    --header 'Content-Type: application/json'
    
    [
        "demo.message"
    ]
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6

    请求API获取新配置

    curl --location --request GET '127.0.0.1:8080/'
    
    newfiles
    
    • 1
    • 2
    • 3

    配置被刷新,符合预期

    1.2 @Value + @RefreshScope + /actuator/refresh

    以下演示 @Value 在指定的配置类中,而非 Controller 中直接引入
    1.2步骤同(1.1 @ConfigurationProperties + /actuator/refresh)

    1. 书写 MyValue ,使用 @Value 的注解获取配置文件参数值
    @Data
    @Configuration
    @RefreshScope
    public class MyValue {
        @Value("${demo.value}")
        private String demoValue;
    }
    
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8

    application.yaml

    server:
      port: 8080
    spring:
      application:
        name: springboot-config-refresh
    management:
      endpoints:
        web:
          exposure:
            include: refresh
      endpoint:
        refresh:
          enabled: true
    demo:
      message: files
      value: files
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    1. 书写值查询的接口进行验证
    @RestController
    @RequestMapping
    public class ValueController {
        @Autowired
        private MyConfig myConfig;
        @Autowired
        private MyValue myValue;
    
        @GetMapping
        public String value(){
         return myConfig.getMessage();
        }
    
        @GetMapping("demo")
        private String demoValue(){
            return myValue.getDemoValue();
        }
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    1. 请求API

    请求API获取初始配置

    curl --location --request GET '127.0.0.1:8080/demo'
    
    files
    
    • 1
    • 2
    • 3

    参照 上一个方法去修改对应配置的值
    调用 /actuator/refresh 方法后,能够获取到最新值

    curl --location --request POST '127.0.0.1:8080/actuator/refresh' \
    --header 'Content-Type: application/json'
    
    [
        "demo.value"
    ]
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    curl --location --request GET '127.0.0.1:8080/demo'
    
    newfiles
    
    • 1
    • 2
    • 3

    2、从外部文件加载和更新应用属性

    这种方法目前用处不多,可以自行参考demo

  • 相关阅读:
    C++之map如何实例化类对象(一百九十九)
    制胜充电桩下半场,特来电、星星充电们要靠运营?
    进程管理(天勤)
    一个有关sizeof的题目
    过滤器和拦截器的区别
    Python数据攻略-Pandas的数据计算、拼接与可视化
    【Rust】002-基础语法:函数
    Hbuilderx:Vue项目打包apk打开首页空白问题
    vite+vue3+ts+eslint配置问题
    实际工作项目中搭配git托管代码的流程
  • 原文地址:https://blog.csdn.net/c_zyer/article/details/132976952