Springboot项目动态加载配置文件及刷新bean

需求

系统遇到这样一个需求,线上环境在配置文件发生变动时,可以不用经过重启,通过刷新接口的方式得到配置文件的加载,主要目的是为了迅速部署,避免因手动重启,处理不及时导致积压的问题

问题

1.程序中如何获取修改后的配置
2.某些配置值是应用在bean里面的,在程序初始化的时候已经注入,如何修改这一部分。
例如,程序是分主备环境的,kafka consumer的groupid或topic根据环境不同而改变,那么consumer若写在bean中,修改配置文件,要一并更新到bean中

//示例代码,KafkaConsumer是自己封装的类
@Bean(name = "consumer")
public KafkaConsumer createKafkaConsumer(
	@Qualifier("service") ExcutorService excutorService) {
	//groupid + topic
	//currEnv 主环境 ““ 备环境”RE_BAK_“
	KafkaConsumer consumer = new KafkaConsumer(currEnv+groupid,topic){
	public void function(ConsumerRecords<String, String> records) { //...业务代码}
  }
}

解决

1.程序中获取修改后的配置,去处理业务逻辑,参考了这篇文章戳我
第一步,添加适合自己springboot版本的Springcloud context依赖,若Springboot版本低,maven可能会引不上高版本的context

<dependency>
	<groupId>org.springframework.cloud</groupId>
	<artifactId>spring-cloud-context</artifactId>
	<version>?</version>
</dependency>

第二步,在需要得到刷新配置值的类上引入@RefreshScope
第三步,在对应变量上引入@Value
第四步,编写refresh接口

package com.example.zzy.zzttest.controller;

import com.example.zzy.zzttest.config.BizConfig;
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.RequestMapping;
import org.springframework.web.bind.annotation.RestController;

@RefreshScope
@RestController
public class TestController {
    @Autowired
    private BizConfig bizConfig;

    @Autowired
    private ContextRefresher contextRefresher;

    @Value("${biz.refresh}")
    private String refresh;

    @RequestMapping(path = "/show")
    public String show() {
        //String ref = bizConfig.getRefresh();
        System.out.println(refresh);
        return refresh;
    }



    @RequestMapping(path = "/refresh")
    public String refresh() throws Exception{
        new Thread( () -> contextRefresher.refresh() ).start();
        return show();
    }
}

p.s.这种方式仅适用于springboot默认管理的配置文件,比如包内的或者包外的application.properties 或者application.yml。一般我们都要更新配置文件了那基本动的都是包外的配置文件,可以直接外置application.properties,把它放在部署包的同级目录,可以达到在controller中获取配置值的目的。关于springboot加载配置文件路径及优先级戳我,总结的很清楚。关于ContextRefresher相关源码解读戳我

p.s.顺便记录一下另外一个问题,我的实际项目没有用到springboot默认的项目内外的application.properties,而是在部署包路径下的/hadoopConf/props.properties中,项目中获取配置的时候使用了工具类,这样做的目的是因为有很多普通项目也引用了这里面的配置,这里不延伸。在这种情况下,因为不是springboot管理的配置文件,所以用上面的方法是不成功的,解决方法是在启动参数里加入

--spring.config.location=./hadoopConf/props.properties

这样springboot会把这个配置文件纳入管理,相当于把它认为是applicaiton.properties,就可以正常使用上面的步骤获取更新的配置值了

2.解决刷新bean的问题,参考链接

你可能感兴趣的:(spring,boot,spring,boot)