前提
在使用nacos的配置中心功能,发现在application.yml中配置地址后仍然读取不到配置中心地址,配置项和值都是正确的。但就是读不到,现在来分析下
配置项
spring:application:name: test-servicemain:allow-bean-definition-overriding: truecloud:nacos:discovery:# 这里私密地址就不透漏了server-addr: xxx:8848config:server-addr: xxx:8848file-extension: yamlshared-configs:- data-id: common.yamlrefresh: 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@ConditionalOnMissingBeanpublic 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配置中心正常读取到。