2012-02-19 84 views
19

使用Spring時,是否可以在傳遞的值不爲null時設置屬性?Spring - 只有當值不爲空時才設置屬性

例子:

<bean name="myBean" class="some.Type"> 
    <property name="abc" value="${some.param}"/> 
</bean> 

我在尋找的行爲是:

some.Type myBean = new some.Type(); 
if (${some.param} != null) myBean.setAbc(${some.param}); 

我之所以需要這個是因爲abc有,我不想覆蓋默認值一個null。 而我創建的Bean不在我的源代碼控制之下 - 所以我無法改變它的行爲。 (另外,abc爲此目的可能是一個原始的,所以我不能用空設置也無妨

編輯:
根據我覺得我的問題需要澄清的答案

我。我需要實例化並傳遞給第三方,這個bean有很多不同類型的屬性(當前有12個)(int,boolean,String等)
每個屬性都有一個默認值 - 我不知道它是什麼,並且寧願不需要知道,除非它成爲問題。 我在尋找的是來自Spring能力的通用解決方案 - 目前我擁有的唯一解決方案是基於反射的解決方案。

配置

<bean id="myBean" class="some.TypeWrapper"> 
    <property name="properties"> 
    <map> 
     <entry key="abc" value="${some.value}"/> 
     <entry key="xyz" value="${some.other.value}"/> 
     ... 
     </map> 
    </property> 
</bean> 

代碼

public class TypeWrapper 
{ 
    private Type innerBean; 

    public TypeWrapper() 
    { 
     this.innerBean = new Type(); 
    } 

    public void setProperties(Map<String,String> properties) 
    { 
     if (properties != null) 
     { 
      for (Entry<String, Object> entry : properties.entrySet()) 
      { 
       String propertyName = entry.getKey(); 
       Object propertyValue = entry.getValue(); 

       setValue(propertyName, propertyValue); 
      } 
     } 
    } 

    private void setValue(String propertyName, Object propertyValue) 
    { 
     if (propertyValue != null) 
     { 
      Method method = getSetter(propertyName); 
      Object value = convertToValue(propertyValue, method.getParameterTypes()[0]); 
      method.invoke(innerBean, value); 
     } 
    } 

    private Method getSetter(String propertyName) 
    { 
     // Assume a valid bean, add a "set" at the beginning and toUpper the 1st character. 
     // Scan the list of methods for a method with the same name, assume it is a "valid setter" (i.e. single argument) 
     ... 
    } 

    private Object convertToValue(String valueAsString, Class type) 
    { 
     // Check the type for all supported types and convert accordingly 
     if (type.equals(Integer.TYPE)) 
     { 
      ... 
     } 
     else if (type.equals(Integer.TYPE)) 
     { 
      ... 
     } 
     ... 
    } 
} 

真正的 「困難」 是在所有可能的值類型實現convertToValue。我已經在我的生活中不止一次地完成了這個任務 - 所以在我需要的所有可能的類型(主要是原語和幾個枚舉)上實現它並不是一個大問題 - 但我希望存在一個更智能的解決方案。

回答

1

您可以創建一個實用工具類,將作爲一個工廠類some.Type,幷包裹有邏輯

例如:

public class TypeFactory { 
    public static Type craeteType(SomeType param){ 
     Type t = new Type(); 
     if(param!=null) 
      t.setParam(param); 
    } 
} 

和XML使用此工廠方法配置bean創建

<bean id="myBean" class="some.Type" 
     factory-method="craeteType"> 
    <constructor-arg ref="param"/> 
</bean> 
3

您可以在Spring框架的屬性configurer中使用默認值概念如下:

<bean name="myBean" class="some.Type"> 
    <property name="abc" value="${some.param : your-default-value}"/> 
</bean> 

您可以通過此方法設置默認值。通過這種上下文配置,如果some.param鍵存在,那麼它的值設置在abc屬性中,如果不存在your-default-value設置在abc屬性中。

注意:這個許可的另一個好處是:「在POJO編程模型中,更好的approzh是類的成員沒有任何默認值,並且從課外注入默認值。「

+0

謝謝你的提示 - 這可能是將來會有幫助,但在我的情況下,我無法使用它 - 正如我所說,這個bean不在我的源代碼控制中 - 所以我不知道它的默認值是什麼(並且不想知道)。我希望得到以下幾行: '' – RonK 2012-02-19 09:37:33

5

爲了解決你的問題,你必須使用SEL 。(春季表達式語言) 通過此功能(在Spring 3.0中加入),你可以如其他動態語言寫你的病情爲您的背景下,答案是:

<bean name="myBean" class="some.Type"> 
    <property name="abc" value="#(if(${some.param} != null) ${some.param})"/> 
</bean> 

更多信息,請參閱(本教程怎麼說在上下文文件中使用SEL): http://static.springsource.org/spring/docs/3.0.5.RELEASE/reference/expressions.html

+6

難道它仍然會通過一個空字符串,如果參數爲空? OP不想傳遞任何東西:他想避免調用setter。 – 2012-02-19 10:34:52

+0

'#{$ {some.param}!= #null? $ {some.param}:#null}似乎更正確 – Vadzim 2013-11-22 13:23:32

0

我找到了與下面的代碼段工作:

<bean name="myBean" class="some.Type"> 
    <property name="abc" value="#{'${some.param}'=='' ? null : '${some.param}'}" /> 
</bean> 
+0

不是我所需要的 - 但無論如何感謝。 – RonK 2012-10-22 13:01:44

+0

@Ronk - 你找到了解決方案嗎?我需要做到這一點,我找不到解決方案。 – dharag 2013-11-21 16:01:40

+0

@dharag - 我最終實現了一個使用FactoryBean創建我想要的對象的基於反射的解決方案。我發現沒有內置的解決方案。 – RonK 2013-11-21 16:19:32

27

您可以使用佔位符機制SpEL和佔位符和默認值一起如下:

<bean name="myBean" class="some.Type"> 
    <property name="abc" value="${some.param:#{null}}"/> 
</bean> 
+0

你已經回答了這個問題一次:)(也有點不同) – RonK 2013-03-17 11:25:04

+1

哦,是的,但更新的答案更簡單:) – MJM 2013-03-18 12:31:35

+0

這是迄今爲止所有答案中最好的解決方案,謝謝你 – 2017-12-21 01:58:35

相關問題