Spring - установить свойство, только если значение не равно нулю - PullRequest
23 голосов
/ 19 февраля 2012

При использовании 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.И Бин, который я создаю, не находится под моим контролем источника, поэтому я не могу изменить его поведение.(Кроме того, abc для этой цели может быть примитивом, поэтому я все равно не могу установить его с нулем.

РЕДАКТИРОВАТЬ:
В соответствии с ответами, я думаю, что мойвопрос требует уточнения.

У меня есть бин, который мне нужно создать и передать третьей стороне, которой я пользуюсь. У этого бина есть много свойств (в настоящее время 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 для всех возможных типов значений. Я делал это более одного раза в своей жизни - поэтому не составляет особой проблемы реализовать его для всех возможных типов, которые мне нужны (в основном примитивы и некоторыеenums) - но я надеялся на более разумное решениеНация существовала.

Ответы [ 6 ]

33 голосов
/ 16 марта 2013

Вы можете использовать SpEL, а также заполнитель и значение по умолчанию для механизмов заполнителей следующим образом:

<bean name="myBean" class="some.Type">
    <property name="abc" value="${some.param:#{null}}"/>
</bean>
5 голосов
/ 19 февраля 2012

Для решения вашей проблемы вы должны использовать SEL (Spring Expression Language). С помощью этой функции (добавленной в 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

3 голосов
/ 19 февраля 2012

Вы можете использовать концепцию значений по умолчанию в настройке свойств Spring Framework следующим образом:

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

вы можете установить значение по умолчанию с помощью этого подхода. В этом контексте конфигурируется, если ключ some.param существует, поэтому его значение устанавливается в свойстве abc, а если не существует, your-default-value устанавливается в свойстве abc.

Примечание. Еще одно преимущество этого подхода заключается в следующем: «В модели программирования POJO лучше использовать класс, у которого нет значения по умолчанию, а значение по умолчанию вводится вне класса».

1 голос
/ 19 февраля 2012

Вы можете создать класс Utility, который будет действовать как класс Factory для some.Type, и обернуть туда логику

Например:

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

и в XML настройте создание компонента с помощью этого метода Factory

<bean id="myBean" class="some.Type"
      factory-method="craeteType">
    <constructor-arg ref="param"/>  
</bean>
0 голосов
/ 22 октября 2012

Я работаю со следующим фрагментом:

<bean name="myBean" class="some.Type">
    <property name="abc" value="#{'${some.param}'=='' ? null : '${some.param}'}" />
</bean>
0 голосов
/ 19 февраля 2012

Это похоже на задание для Конфигурация контейнера на основе Java .Вы сможете делать то, что делаете в своей конфигурации XML, но со всей мощью Java.

...