web-dev-qa-db-fra.com

Spring - définit une propriété uniquement si la valeur n'est pas null

Lors de l'utilisation de Spring, est-il possible de définir une propriété uniquement si la valeur transmise n'est pas null?

Exemple:

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

Le comportement que je recherche est:

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

J'en ai besoin parce que abc a une valeur par défaut que je ne souhaite pas remplacer par un null. Et le bean que je crée n'est pas sous mon contrôle de source - je ne peux donc pas changer son comportement. (De plus, abc à cette fin pourrait être une primitive, je ne peux donc pas le définir avec une valeur null de toute façon.

MODIFIER:
Selon les réponses, je pense que ma question nécessite des éclaircissements.

J'ai haricot j'ai besoin d'instancier et de passer au tiers que j'utilise. Ce haricot a de nombreuses propriétés (12 actuellement) de différents types (int, boolean, String, etc.)
Chaque propriété a une valeur par défaut - je ne sais pas ce que c'est et préférerais ne pas avoir besoin de savoir à moins que cela ne devienne un problème. Ce que je recherche, c'est une solution générique des capacités de Spring - actuellement, la seule solution que je dispose est basée sur la réflexion.

Configuration

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

Code

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))
        {
          ...
        }
        ...
    }
}

La vraie "difficulté" est d’appliquer convertToValue pour tous les types de valeur possibles. Je l’ai fait plus d’une fois dans ma vie - il n’est donc pas très difficile de l’appliquer pour tous les types possibles dont j’ai besoin primitifs et quelques enums) - mais j’espérais une solution plus intelligente.

20
RonK

Vous pouvez utiliser SpEL et la valeur de substitution et la valeur par défaut pour les mécanismes de substitution en procédant comme suit:

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

Pour résoudre votre problème, vous devez utiliser le langage SEL (Spring Expression Language). Cette fonctionnalité (ajoutée dans SPring 3.0) vous permet, par exemple, d’écrire un autre langage dynamique. Pour votre contexte, la réponse est:

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

pour plus d'informations, voir (ce didacticiel explique ce que vous utilisez SEL dans un fichier de contexte): http://static.springsource.org/spring/docs/3.0.5.RELEASE/reference/expressions.html

5
Sam

Vous pouvez utiliser le concept de valeur par défaut dans la configuration de la propriété dans la structure Spring comme suit:

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

vous pouvez définir la valeur par défaut avec cette approche. Par ce contexte, config si la clé some.param existe et que sa valeur est définie dans la propriété abc et si elle n’existe pas, your-default-value est définie dans la propriété abc.

Remarque: Un autre avantage de cette approche est: "Dans le modèle de programmation POJO, une meilleure approche est que le membre de la classe n'a pas de valeur par défaut et que la valeur par défaut est injectée hors classe."

3
Sam

Vous pouvez créer une classe Utility qui agira comme une classe Factory pour some.Type, et y encapsuler la logique.

Par exemple : 

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

et sur XML, configurez la création du bean en utilisant cette méthode Factory

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

Je le travaille avec l'extrait suivant:

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

Cela ressemble à un travail pour Configuration du conteneur Java . Vous serez capable de faire ce que vous faites dans votre configuration XML, mais avec toute la puissance de Java.

0
JB Nizet