您好,登錄后才能下訂單哦!
本文小編為大家詳細介紹“Springboot @Value注入boolean如何設置默認值”,內容詳細,步驟清晰,細節處理妥當,希望這篇“Springboot @Value注入boolean如何設置默認值”文章能幫助大家解決疑惑,下面跟著小編的思路慢慢深入,一起來學習新知識吧。
Springboot 中讀取配置文件
test:
業務代碼如下
@Value("${test:true}") private boolean test;
報錯如下
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}") private String test;
于是更改了接收類型,看看獲取到的值是否是 true,結果發現 test 值為 “”,而不是設置的默認值
報錯問題在于只要配置文件中有 test: 所以系統就默認 test 為 “” 而不是按照我所設想的為空所以默認值為 true。
直接刪除配置文件中的 test: 即可正常啟動。
在排查問題的過程中也粗略的跟讀了一下源碼
//org.springframework.beans.TypeConverterSupport#doConvert() private <T> T doConvert(Object value, Class<T> requiredType, MethodParameter methodParam, Field field) throws TypeMismatchException { try { return field != null ? this.typeConverterDelegate.convertIfNecessary(value, requiredType, field) : this.typeConverterDelegate.convertIfNecessary(value, requiredType, methodParam); } catch (ConverterNotFoundException var6) { throw new ConversionNotSupportedException(value, requiredType, var6); } catch (ConversionException var7) { throw new TypeMismatchException(value, requiredType, var7); } catch (IllegalStateException var8) { throw new ConversionNotSupportedException(value, requiredType, var8); } catch (IllegalArgumentException var9) { // 最終異常從這里拋出 throw new TypeMismatchException(value, requiredType, var9); } }
最終賦值在
//org.springframework.beans.TypeConverterDelegate#doConvertTextValue() private Object doConvertTextValue(Object oldValue, String newTextValue, PropertyEditor editor) { try { editor.setValue(oldValue); } 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
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(); }
讀到這里,這篇“Springboot @Value注入boolean如何設置默認值”文章已經介紹完畢,想要掌握這篇文章的知識點還需要大家自己動手實踐使用過才能領會,如果想了解更多相關內容的文章,歡迎關注億速云行業資訊頻道。
免責聲明:本站發布的內容(圖片、視頻和文字)以原創、轉載和分享為主,文章觀點不代表本網站立場,如果涉及侵權請聯系站長郵箱:is@yisu.com進行舉報,并提供相關證據,一經查實,將立刻刪除涉嫌侵權內容。