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对象,然后从这些对象中提取特定的配置信息。以下是该代码的主要步骤和功能:
-
获取配置:使用
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");
这是尝试通过直接拼接键名来获取配置值的方式,证明是不可行的,必须逐层解析配置对象来获取值。