问题描述
在SpringBoot的项目代码中需要使用到如下方式从yml配置文件中读取并注入字段属性:
@Value("${config.param:on}")
private String param;
当nacos中的yml配置文件没有这个配置的时候,代码读取注解上的默认值,运行正常
当nacos中的yml配置文件增加了这个配置时,代码运行异常,打断点后发现,param这个值注入的属性值为String类型的true,百思不得其解这个true是从哪来的。
产生原因
在SpringBoot的项目中,当在配置文件中配置的值为yes/no或者on/off时,在SpringBoot内部解析时会将yes/no,on/off解析为true/false
SpringBoot启动加载配置时的部分源码:
public class SafeConstructor extends BaseConstructor {
public SafeConstructor(LoaderOptions loadingConfig) {
super(loadingConfig);
this.yamlConstructors.put(Tag.NULL, new SafeConstructor.ConstructYamlNull());
this.yamlConstructors.put(Tag.BOOL, new SafeConstructor.ConstructYamlBool());
}
public class ConstructYamlBool extends AbstractConstruct {
public ConstructYamlBool() {
}
public Object construct(Node node) {
String val = SafeConstructor.this.constructScalar((ScalarNode)node);
return SafeConstructor.BOOL_VALUES.get(val.toLowerCase());
}
}
static {
BOOL_VALUES.put("yes", Boolean.TRUE);
BOOL_VALUES.put("no", Boolean.FALSE);
BOOL_VALUES.put("true", Boolean.TRUE);
BOOL_VALUES.put("false", Boolean.FALSE);
BOOL_VALUES.put("on", Boolean.TRUE);
BOOL_VALUES.put("off", Boolean.FALSE);
RADIX_MAX = new int[17][2];
int[] radixList = new int[]{2, 8, 10, 16};
int[] var1 = radixList;
int var2 = radixList.length;
for(int var3 = 0; var3 < var2; ++var3) {
int radix = var1[var3];
RADIX_MAX[radix] = new int[]{maxLen(2147483647, radix), maxLen(9223372036854775807L, radix)};
}
TIMESTAMP_REGEXP = Pattern.compile("^([0-9][0-9][0-9][0-9])-([0-9][0-9]?)-([0-9][0-9]?)(?:(?:[Tt]|[ \t]+)([0-9][0-9]?):([0-9][0-9]):([0-9][0-9])(?:\\.([0-9]*))?(?:[ \t]*(?:Z|([-+][0-9][0-9]?)(?::([0-9][0-9])?)?))?)?$");
YMD_REGEXP = Pattern.compile("^([0-9][0-9][0-9][0-9])-([0-9][0-9]?)-([0-9][0-9]?)$");
}
}
解决方案
- 最直接的方法,不要使用yes/no,on/off这些关键字。
- 实在要使用,给这些值加上单引号或者双引号。