Spring boot @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: 即可正常啓動。

@Value 源碼閱讀

在排查問題的過程中也粗略的跟讀了一下源碼

//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

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章