springboot @value注解,springboot value注解默认值
目录
@值注入布尔型设置默认值问题描述问题分析解决方案@值源码阅读弹簧解析@值
@Value注入boolean设置默认值
问题描述
跳靴中读取配置文件
测试:业务代码如下
@Value(${test:true} )私有布尔测试;报错如下
嵌套异常为org。spring框架。豆子。typemismatchexception异常:无法将" java.lang.String "类型的值转换为所需的"布尔型"类型;嵌套异常是Java。郎。illegalargumentexception :无效的布尔值[]
问题分析
根据报错可知,主要问题在于注入时试验的值是线类型,无法转换成布尔型类型。
@Value(${test:true} )私有字符串测试;于是更改了接收类型,看看获取到的值是否是没错,结果发现试验值为"",而不是设置的默认值
解决方案
报错问题在于只要配置文件中有测试:所以系统就默认试验为"" 而不是按照我所设想的为空所以默认值为没错。
直接删除配置文件中的测试:即可正常启动。
@Value 源码阅读
在排查问题的过程中也粗略的跟读了一下源码
//org。spring框架。豆子。typeconvertersupport # doConvert()private T T doConvert(对象值,ClassT必需类型,方法参数方法参数,字段字段)抛出类型匹配异常{ try { return Field!=null?这个。typeconverterdelegate。convert required(value,requiredType,field): this。typeconverterdelegate。convert必要性(value,requiredType,method param);} catch(ConverterNotFoundException var 6){ throw new ConversionNotSupportedException(value,requiredType,var 6);} catch(转换异常var 7){ throw new typemismatch异常(value,requiredType,var 7);} catch(IllegalStateException var 8){ throw new ConversionNotSupportedException(value,requiredType,var 8);} catch(IllegalArgumentException var 9){//最终异常从这里抛出抛出新的TypeMismatchException(value,requiredType,var 9);}}最终赋值在
//org。spring框架。豆子。typeconverterdelegate # doConvertTextValue()私有对象doConvertTextValue(对象旧值,字符串newTextValue,属性编辑器编辑器){ try { editor。setvalue(旧值);
} catch (Exception var5) { if (logger.isDebugEnabled()) { logger.debug("PropertyEditor [" + editor.getClass().getName() + "] does not support setValue call", var5); } } // 此处发现 newTextValue 为 "" editor.setAsText(newTextValue); return editor.getValue();}接下来就是如何将 字符串 true 转换为 boolean 的具体代码:
// org.springframework.beans.propertyeditors.CustomBooleanEditor#setAsText() public void setAsText(String text) throws IllegalArgumentException { String input = text != null ? text.trim() : null; if (this.allowEmpty && !StringUtils.hasLength(input)) { this.setValue((Object)null); } else if (this.trueString != null && this.trueString.equalsIgnoreCase(input)) { this.setValue(Boolean.TRUE); } else if (this.falseString != null && this.falseString.equalsIgnoreCase(input)) { this.setValue(Boolean.FALSE); } else if (this.trueString != null !"true".equalsIgnoreCase(input) && !"on".equalsIgnoreCase(input) && !"yes".equalsIgnoreCase(input) && !"1".equals(input)) { if (this.falseString != null !"false".equalsIgnoreCase(input) && !"off".equalsIgnoreCase(input) && !"no".equalsIgnoreCase(input) && !"0".equals(input)) { throw new IllegalArgumentException("Invalid boolean value [" + text + "]"); } this.setValue(Boolean.FALSE); } else { this.setValue(Boolean.TRUE); } }
tips:windows 中使用 IDEA 去查找类可以使用 ctrl + shift +alt +N的快捷键组合去查询,mac 系统则是 commond + O
Spring解析@Value
1、初始化PropertyPlaceholderHelper对象
protected String placeholderPrefix = "${"; protected String placeholderSuffix = "}"; @Nullable protected String valueSeparator = ":"; private static final Map<String, String> wellKnownSimplePrefixes = new HashMap<>(4); static { wellKnownSimplePrefixes.put("}", "{"); wellKnownSimplePrefixes.put("]", "["); wellKnownSimplePrefixes.put(")", "("); } public PropertyPlaceholderHelper(String placeholderPrefix, String placeholderSuffix, @Nullable String valueSeparator, boolean ignoreUnresolvablePlaceholders) { Assert.notNull(placeholderPrefix, "placeholderPrefix must not be null"); Assert.notNull(placeholderSuffix, "placeholderSuffix must not be null"); //默认值${ this.placeholderPrefix = placeholderPrefix; //默认值} this.placeholderSuffix = placeholderSuffix; String simplePrefixForSuffix = wellKnownSimplePrefixes.get(this.placeholderSuffix); //当前缀为空或跟定义的不匹配,取传入的前缀 if (simplePrefixForSuffix != null && this.placeholderPrefix.endsWith(simplePrefixForSuffix)) { this.simplePrefix = simplePrefixForSuffix; } else { this.simplePrefix = this.placeholderPrefix; } //默认值: this.valueSeparator = valueSeparator; this.ignoreUnresolvablePlaceholders = ignoreUnresolvablePlaceholders; }
2、解析@Value
protected String parseStringValue( String value, PlaceholderResolver placeholderResolver, Set<String> visitedPlaceholders) { StringBuilder result = new StringBuilder(value); //是否包含前缀,返回第一个前缀的开始index int startIndex = value.indexOf(this.placeholderPrefix); while (startIndex != -1) { //找到最后一个后缀的index int endIndex = findPlaceholderEndIndex(result, startIndex); if (endIndex != -1) { //去掉前缀后缀,取出里面的字符串 String placeholder = result.substring(startIndex + this.placeholderPrefix.length(), endIndex); String originalPlaceholder = placeholder; if (!visitedPlaceholders.add(originalPlaceholder)) { throw new IllegalArgumentException( "Circular placeholder reference " + originalPlaceholder + " in property definitions"); } // 递归判断是否存在占位符,可以这样写${acm.endpoint:${address.server.domain:}} placeholder = parseStringValue(placeholder, placeholderResolver, visitedPlaceholders); // 根据key获取对应的值 String propVal = placeholderResolver.resolvePlaceholder(placeholder); // 值不存在,但存在默认值的分隔符 if (propVal == null && this.valueSeparator != null) { // 获取默认值的索引 int separatorIndex = placeholder.indexOf(this.valueSeparator); if (separatorIndex != -1) { // 切掉默认值的字符串 String actualPlaceholder = placeholder.substring(0, separatorIndex); // 切出默认值 String defaultValue = placeholder.substring(separatorIndex + this.valueSeparator.length()); // 根据新的key获取对应的值 propVal = placeholderResolver.resolvePlaceholder(actualPlaceholder); // 如果值不存在,则把默认值赋值给当前值 if (propVal == null) { propVal = defaultValue; } } } // 如果当前值不为NULL if (propVal != null) { // 递归获取存在占位符的值信息 propVal = parseStringValue(propVal, placeholderResolver, visitedPlaceholders); // 替换占位符 result.replace(startIndex, endIndex + this.placeholderSuffix.length(), propVal); if (logger.isTraceEnabled()) { logger.trace("Resolved placeholder " + placeholder + ""); } startIndex = result.indexOf(this.placeholderPrefix, startIndex + propVal.length()); } else if (this.ignoreUnresolvablePlaceholders) { // Proceed with unprocessed value. startIndex = result.indexOf(this.placeholderPrefix, endIndex + this.placeholderSuffix.length()); } else { throw new IllegalArgumentException("Could not resolve placeholder " + placeholder + "" + " in value "" + value + """); } visitedPlaceholders.remove(originalPlaceholder); } else { startIndex = -1; } } return result.toString(); }
以上为个人经验,希望能给大家一个参考,也希望大家多多支持盛行IT。
郑重声明:本文由网友发布,不代表盛行IT的观点,版权归原作者所有,仅为传播更多信息之目的,如有侵权请联系,我们将第一时间修改或删除,多谢。