前提
在使用nacos的配置中心功能,发现在application.yml中配置地址后仍然读取不到配置中心地址,配置项和值都是正确的。但就是读不到,现在来分析下
配置项
spring:
application:
name: test-service
main:
allow-bean-definition-overriding: true
cloud:
nacos:
discovery:
# 这里私密地址就不透漏了
server-addr: xxx:8848
config:
server-addr: xxx:8848
file-extension: yaml
shared-configs:
- data-id: common.yaml
refresh: true
分析
在项目启动时,发现有输出关于nacos配置中心warn级别的日志
NacosPropertySourceBuilder:87 - Ignore the empty nacos configuration and get it based on dataId[test-service] & group[DEFAULT_GROUP]
从这行入手,分析NacosPropertySourceBuilder.loadNacosData
private List<PropertySource<?>> loadNacosData(String dataId, String group,
String fileExtension) {
String data = null;
try {
data = configService.getConfig(dataId, group, timeout);
if (StringUtils.isEmpty(data)) {
log.warn(
"Ignore the empty nacos configuration and get it based on dataId[{}] & group[{}]",
dataId, group);
return Collections.emptyList();
}
if (log.isDebugEnabled()) {
log.debug(String.format(
"Loading nacos data, dataId: '%s', group: '%s', data: %s", dataId,
group, data));
}
return NacosDataParserHandler.getInstance().parseNacosData(dataId, data,
fileExtension);
}
catch (NacosException e) {
log.error("get data from Nacos error,dataId:{} ", dataId, e);
}
catch (Exception e) {
log.error("parse data from Nacos error,dataId:{},data:{}", dataId, data, e);
}
return Collections.emptyList();
}
可以看到configService.getConfig(dataId, group, timeout);
这行是获取数据,并且入参dataId
、group
、fileExtension
能够想到是配置的参数
能够看到fileExtension
参数值是properties,但我们在配置文件配置了是yaml,这是怎么回事呢,我们分析这个参数的由来
NacosPropertySourceLocator#loadApplicationConfiguration
private void loadApplicationConfiguration(
CompositePropertySource compositePropertySource, String dataIdPrefix,
NacosConfigProperties properties, Environment environment) {
String fileExtension = properties.getFileExtension();
//省略...
}
fileExtension参数由NacosConfigProperties而来,从这个名字就能想到,这个类就是配置参数
##NacosConfigProperties ##
@ConfigurationProperties(NacosConfigProperties.PREFIX)
public class NacosConfigProperties {
/**
* Prefix of {@link NacosConfigProperties}.
*/
public static final String PREFIX = "spring.cloud.nacos.config";
/**
* COMMAS , .
*/
public static final String COMMAS = ",";
/**
* SEPARATOR , .
*/
public static final String SEPARATOR = "[,]";
private static final Pattern PATTERN = Pattern.compile("-(\\w)");
/**
* nacos config server address.
*/
private String serverAddr;
/**
* the nacos authentication username.
*/
private String username;
/**
* the nacos authentication password.
*/
private String password;
/**
* encode for nacos config content.
*/
private String encode;
/**
* nacos config group, group is config data meta info.
*/
private String group = "DEFAULT_GROUP";
/**
* nacos config dataId prefix.
*/
private String prefix;
/**
* the suffix of nacos config dataId, also the file extension of config content.
*/
private String fileExtension = "properties";
//省略...
}
fileExtension
果然就是我们要分析的参数,默认值properties
,说明我们指定的yaml没有设置成功,接下面我们分析NacosConfigProperties
配置参数类是怎么进行赋值的即可
@Configuration(proxyBeanMethods = false)
@ConditionalOnProperty(name = "spring.cloud.nacos.config.enabled", matchIfMissing = true)BootstrapConfiguration
public class NacosConfigBootstrapConfiguration {
@Bean
@ConditionalOnMissingBean
public NacosConfigProperties nacosConfigProperties() {
return new NacosConfigProperties();
}
}
根据多次翻看源码的经验,NacosConfigBootstrapConfiguration
这个类肯定是靠springboot自动装配原理加载的
但要注意NacosConfigBootstrapConfiguration
是由BootstrapConfiguration
来指定加载的而不是EnableAutoConfiguration
指定来加载的。
重点
BootstrapConfiguration
指定的进行自动装配的类只能读取bootstrap.properties或者bootstrap.yaml的配置,applicaton.properties和applicaton.yaml是不会读取的EnableAutoConfiguration
可以读取bootstrap.properties或者bootstrap.yaml和applicaton.properties和applicaton.yaml
解决办法
知道了问题所在,我们使用bootstrap.yaml配置即可
fileExtension正常读取到位yaml,数据也从nacos配置中心正常读取到。