1. 首页
  2. 软件开发
  3. JAVA
  4. 用Java代码从Nacos配置中心读取Spring boot程序的 yaml 格式配置文件内容

用Java代码从Nacos配置中心读取Spring boot程序的 yaml 格式配置文件内容

  • 发布于 2024-08-14
  • 0 次阅读

本文由 简悦 SimpRead 转码, 原文地址 blog.csdn.net

Spring Cloud Alibaba (https://gitee.com/mirrors/Spring-Cloud-Alibaba)示例代码 spring-cloud-alibaba-examples 的 Integerated-example 项目中,integrated-praise-consumer 模块中,在 YamlConfigParser 类中,实现了从 Nacos 配置中心读取 Spring boot 程序的 yaml 格式配置文件内容的功能。

这个类的代码如下:

public class YamlConfigParser {
    @Autowired
    private NacosConfigManager nacosConfigManager;
 
    private Integer pullInterval = 4000;
    private Integer pullBatchSize = 4;
 
    private Integer minThread = 2; // 设置最小消费线程数
    private Integer maxThread = 32; // 设置最大消费线程数
    private String consumerGroup; // 消费者组
    private String  nameSrvAddr; // 命名服务器地址和端口号
    private String topic; // 消息主题
 
    public YamlConfigParser() {
    }
 
    public void getConfig(){
        String cfg = "";
        try {
            ConfigService configService = nacosConfigManager.getConfigService();
            cfg = configService.getConfig("integrated-consumer.yaml", "integrated-example", 2000);
            System.out.println("获取到配置信息--------------");
            System.out.println(cfg);
        }catch (NacosException e){
            e.printStackTrace();
        }
        if(cfg.length() == 0)
            return ;
 
        // 将字符串转换为字节数组
        byte[] bytes = cfg.getBytes(StandardCharsets.UTF_8);
        Yaml yaml = new Yaml();
        try (InputStream in = new ByteArrayInputStream(bytes)) {
            Map<String, Object> config = yaml.load(in);
 
            // 需要按照配置文件逐层解析并访问配置信息
            Map<String, Object> springConfig = (Map<String, Object>) config.get("spring");
            Map<String, Object> cloudConfig = (Map<String, Object>) springConfig.get("cloud");
            Map<String, Object> streamConfig = (Map<String, Object>) cloudConfig.get("stream");
            Map<String, Object> bindingsConfig = (Map<String, Object>) streamConfig.get("bindings");
            Map<String, Object> inputConfig = (Map<String, Object>) bindingsConfig.get("praise-input");
 
            // topic = (String) config.get("spring.cloud.stream.bindings.praise-input.destination"); // 不支持这种用法,取不到值
            topic = (String) inputConfig.get("destination");
            consumerGroup = (String) inputConfig.get("group");
 
            Map<String, Object> rocketmqConfig = (Map<String, Object>) streamConfig.get("rocketmq");
            Map<String, Object> binderConfig = (Map<String, Object>) rocketmqConfig.get("binder");
            nameSrvAddr = (String)binderConfig.get("name-server");
 
            Map<String, Object> mqbindingsConfig = (Map<String, Object>) rocketmqConfig.get("bindings");
            Map<String, Object> mqpraiseinputConfig = (Map<String, Object>) mqbindingsConfig.get("praise-input");
            Map<String, Object> consumerinputConfig = (Map<String, Object>) mqpraiseinputConfig.get("consumer");
 
            pullInterval = (Integer)consumerinputConfig.get("pullInterval");
            pullBatchSize = (Integer)consumerinputConfig.get("pullBatchSize");
 
            // 输出配置信息
            System.out.println("nameSrvAddr: " + nameSrvAddr);
            System.out.println("consumerGroup: " + consumerGroup);
            System.out.println("topic: " + topic);
            System.out.println("pullInterval: " + pullInterval);
            System.out.println("pullBatchSize: " + pullBatchSize);
        } catch (Exception e) {
            e.printStackTrace();
        }
    }
 
    public Integer getPullInterval() {
        return pullInterval;
    }
    public void setPullInterval(Integer pullInterval) {
        this.pullInterval = pullInterval;
    }
    public Integer getPullBatchSize() {
        return pullBatchSize;
    }
    public void setPullBatchSize(Integer pullBatchSize) {
        this.pullBatchSize = pullBatchSize;
    }
    public Integer getMinThread() {
        return minThread;
    }
    public void setMinThread(Integer minThread) {
        this.minThread = minThread;
    }
    public Integer getMaxThread() {
        return maxThread;
    }
    public void setMaxThread(Integer maxThread) {
        this.maxThread = maxThread;
    }
    public String getConsumerGroup() {
        return consumerGroup;
    }
    public void setConsumerGroup(String consumerGroup) {
        this.consumerGroup = consumerGroup;
    }
    public String getNameSrvAddr() {
        return nameSrvAddr;
    }
    public void setNameSrvAddr(String nameSrvAddr) {
        this.nameSrvAddr = nameSrvAddr;
    }
    public String getTopic() {
        return topic;
    }
    public void setTopic(String topic) {
        this.topic = topic;
    }
}

读取的 integrated-consumer.yaml 文件内容如下:

spring:
  datasource:
    url: jdbc:mysql://integrated-mysql:3306/integrated_praise?useSSL=false&characterEncoding=utf8
  cloud:
    stream:
      bindings:
        praise-input:
          destination: PRAISE-TOPIC-01
          content-type: application/json
          group: praise-consumer-group-PRAISE-TOPIC-01
      rocketmq:
        binder:
          name-server: rocketmq:9876
        bindings:
          praise-input:
            consumer:
              pullInterval: 4000
              pullBatchSize: 4

代码中 getConfig() 方法功能是从 Nacos 配置中心获取名为integrated-consumer.yaml的配置文件,并将其内容解析为 Java 对象,然后从这些对象中提取特定的配置信息。以下是该代码的主要步骤和功能:

  1. 获取配置:使用ConfigService从 Nacos 配置中心获取名为integrated-consumer.yaml的配置,配置文件的命名空间(namespace)是integrated-example,并设置超时时间为 2000 毫秒。
ConfigService configService = nacosConfigManager.getConfigService();
cfg = configService.getConfig("integrated-consumer.yaml", "integrated-example", 2000);

2. 配置解析:将获取到的字符串配置cfg转换为字节数组,然后使用Yaml库将其解析为Map<String, Object>对象。

byte[] bytes = cfg.getBytes(StandardCharsets.UTF_8);
Yaml yaml = new Yaml();
try (InputStream in = new ByteArrayInputStream(bytes)) {
Map<String, Object> config = yaml.load(in);
}

3. 逐层解析配置:通过逐层访问Map对象,提取特定的配置信息,如topic、consumerGroup和nameSrvAddr等。

Map<String, Object> springConfig = (Map<String, Object>) config.get("spring");
Map<String, Object> cloudConfig = (Map<String, Object>) springConfig.get("cloud");
// ... 更多的逐层解析 ...
topic = (String) inputConfig.get("destination");
consumerGroup = (String) inputConfig.get("group");
nameSrvAddr = (String)binderConfig.get("name-server");

需要注意的是,这段代码假设 YAML 配置文件的结构是已知的,并且能够通过链式调用get方法访问到相应的配置信息。如果配置文件的结构发生变化,或者某个键不存在,这段代码将会抛出NullPointerException。

此外,这段代码还展示了如何从一个复杂的嵌套结构中提取特定的配置值,这在处理复杂的配置文件时是非常常见的。

代码中

// 不支持这种用法,取不到值
 
topic = (String) config.get("spring.cloud.stream.bindings.praise-input.destination");

这是尝试通过直接拼接键名来获取配置值的方式,证明是不可行的,必须逐层解析配置对象来获取值。