Springboot @Value注入boolean如何设置默认值
Springboot @Value注入boolean如何设置默认值
本文小编为大家详细介绍“Springboot@Value注入boolean如何设置默认值”,内容详细,步骤清晰,细节处理妥当,希望这篇“Springboot@Value注入boolean如何设置默认值”文章能帮助大家解决疑惑,下面跟着小编的思路慢慢深入,一起来学习新知识吧。
@Value注入boolean设置默认值
问题描述
Springboot 中读取配置文件
test:
业务代码如下
@Value("${test:true}")privatebooleantest;
报错如下
nested exception is org.springframework.beans.TypeMismatchException: Failed to convert value of type 'java.lang.String' to required type 'boolean'; nested exception is java.lang.IllegalArgumentException: Invalid boolean value []
问题分析
根据报错可知,主要问题在于 注入时 test 的值是 String 类型,无法转换成 boolean 类型。
@Value("${test:true}")privateStringtest;
于是更改了接收类型,看看获取到的值是否是 true,结果发现 test 值为 “”,而不是设置的默认值
解决方案
报错问题在于只要配置文件中有 test: 所以系统就默认 test 为 “” 而不是按照我所设想的为空所以默认值为 true。
直接删除配置文件中的 test: 即可正常启动。
@Value 源码阅读
在排查问题的过程中也粗略的跟读了一下源码
//org.springframework.beans.TypeConverterSupport#doConvert()private<T>TdoConvert(Objectvalue,Class<T>requiredType,MethodParametermethodParam,Fieldfield)throwsTypeMismatchException{try{returnfield!=null?this.typeConverterDelegate.convertIfNecessary(value,requiredType,field):this.typeConverterDelegate.convertIfNecessary(value,requiredType,methodParam);}catch(ConverterNotFoundExceptionvar6){thrownewConversionNotSupportedException(value,requiredType,var6);}catch(ConversionExceptionvar7){thrownewTypeMismatchException(value,requiredType,var7);}catch(IllegalStateExceptionvar8){thrownewConversionNotSupportedException(value,requiredType,var8);}catch(IllegalArgumentExceptionvar9){//最终异常从这里抛出thrownewTypeMismatchException(value,requiredType,var9);}}
最终赋值在
//org.springframework.beans.TypeConverterDelegate#doConvertTextValue()privateObjectdoConvertTextValue(ObjectoldValue,StringnewTextValue,PropertyEditoreditor){try{editor.setValue(oldValue);}catch(Exceptionvar5){if(logger.isDebugEnabled()){logger.debug("PropertyEditor["+editor.getClass().getName()+"]doesnotsupportsetValuecall",var5);}}//此处发现newTextValue为""editor.setAsText(newTextValue);returneditor.getValue();}
接下来就是如何将 字符串 true 转换为 boolean 的具体代码:
//org.springframework.beans.propertyeditors.CustomBooleanEditor#setAsText()publicvoidsetAsText(Stringtext)throwsIllegalArgumentException{Stringinput=text!=null?text.trim():null;if(this.allowEmpty&&!StringUtils.hasLength(input)){this.setValue((Object)null);}elseif(this.trueString!=null&&this.trueString.equalsIgnoreCase(input)){this.setValue(Boolean.TRUE);}elseif(this.falseString!=null&&this.falseString.equalsIgnoreCase(input)){this.setValue(Boolean.FALSE);}elseif(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)){thrownewIllegalArgumentException("Invalidbooleanvalue["+text+"]");}this.setValue(Boolean.FALSE);}else{this.setValue(Boolean.TRUE);}}
tips:windows 中使用 IDEA 去查找类可以使用 ctrl + shift +alt +N的快捷键组合去查询,mac 系统则是 commond + O
Spring解析@Value
1、初始化PropertyPlaceholderHelper对象
protectedStringplaceholderPrefix="${";protectedStringplaceholderSuffix="}";@NullableprotectedStringvalueSeparator=":";privatestaticfinalMap<String,String>wellKnownSimplePrefixes=newHashMap<>(4);static{wellKnownSimplePrefixes.put("}","{");wellKnownSimplePrefixes.put("]","[");wellKnownSimplePrefixes.put(")","(");}publicPropertyPlaceholderHelper(StringplaceholderPrefix,StringplaceholderSuffix,@NullableStringvalueSeparator,booleanignoreUnresolvablePlaceholders){Assert.notNull(placeholderPrefix,"'placeholderPrefix'mustnotbenull");Assert.notNull(placeholderSuffix,"'placeholderSuffix'mustnotbenull");//默认值${this.placeholderPrefix=placeholderPrefix;//默认值}this.placeholderSuffix=placeholderSuffix;StringsimplePrefixForSuffix=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
protectedStringparseStringValue(Stringvalue,PlaceholderResolverplaceholderResolver,Set<String>visitedPlaceholders){StringBuilderresult=newStringBuilder(value);//是否包含前缀,返回第一个前缀的开始indexintstartIndex=value.indexOf(this.placeholderPrefix);while(startIndex!=-1){//找到最后一个后缀的indexintendIndex=findPlaceholderEndIndex(result,startIndex);if(endIndex!=-1){//去掉前缀后缀,取出里面的字符串Stringplaceholder=result.substring(startIndex+this.placeholderPrefix.length(),endIndex);StringoriginalPlaceholder=placeholder;if(!visitedPlaceholders.add(originalPlaceholder)){thrownewIllegalArgumentException("Circularplaceholderreference'"+originalPlaceholder+"'inpropertydefinitions");}//递归判断是否存在占位符,可以这样写${acm.endpoint:${address.server.domain:}}placeholder=parseStringValue(placeholder,placeholderResolver,visitedPlaceholders);//根据key获取对应的值StringpropVal=placeholderResolver.resolvePlaceholder(placeholder);//值不存在,但存在默认值的分隔符if(propVal==null&&this.valueSeparator!=null){//获取默认值的索引intseparatorIndex=placeholder.indexOf(this.valueSeparator);if(separatorIndex!=-1){//切掉默认值的字符串StringactualPlaceholder=placeholder.substring(0,separatorIndex);//切出默认值StringdefaultValue=placeholder.substring(separatorIndex+this.valueSeparator.length());//根据新的key获取对应的值propVal=placeholderResolver.resolvePlaceholder(actualPlaceholder);//如果值不存在,则把默认值赋值给当前值if(propVal==null){propVal=defaultValue;}}}//如果当前值不为NULLif(propVal!=null){//递归获取存在占位符的值信息propVal=parseStringValue(propVal,placeholderResolver,visitedPlaceholders);//替换占位符result.replace(startIndex,endIndex+this.placeholderSuffix.length(),propVal);if(logger.isTraceEnabled()){logger.trace("Resolvedplaceholder'"+placeholder+"'");}startIndex=result.indexOf(this.placeholderPrefix,startIndex+propVal.length());}elseif(this.ignoreUnresolvablePlaceholders){//Proceedwithunprocessedvalue.startIndex=result.indexOf(this.placeholderPrefix,endIndex+this.placeholderSuffix.length());}else{thrownewIllegalArgumentException("Couldnotresolveplaceholder'"+placeholder+"'"+"invalue\""+value+"\"");}visitedPlaceholders.remove(originalPlaceholder);}else{startIndex=-1;}}returnresult.toString();}
读到这里,这篇“Springboot@Value注入boolean如何设置默认值”文章已经介绍完毕,想要掌握这篇文章的知识点还需要大家自己动手实践使用过才能领会,如果想了解更多相关内容的文章,欢迎关注恰卡编程网行业资讯频道。
推荐阅读
-
springboot实现基于aop的切面日志
本文实例为大家分享了springboot实现基于aop的切面日志的具体代码,供大家参考,具体内容如下通过aop的切面方式实现日志...
-
SpringBoot定时任务功能怎么实现
-
SpringBoot中的@Import注解怎么使用
-
SpringBoot整合Lombok及常见问题怎么解决
-
springboot图片验证码功能模块怎么实现
-
Springboot+SpringSecurity怎么实现图片验证码登录
-
SpringBoot注解的知识点有哪些
SpringBoot注解的知识点有哪些这篇“SpringBoot注...
-
SpringBoot2.x中management.security.enabled=false无效怎么解决
-
springboot怎么禁用某项健康检查
springboot怎么禁用某项健康检查今天小编给大家分享一下sp...
-
SpringBoot2怎么自定义端点