Puis-je définir null comme valeur par défaut pour une @Value au printemps?

100

J'utilise actuellement l'annotation @Value Spring 3.1.x comme ceci:

@Value("${stuff.value:}")
private String value;

Cela place une chaîne vide dans la variable si l'attribut n'est pas présent. Je voudrais avoir null comme valeur par défaut au lieu d'une chaîne vide. Bien sûr, je souhaite également éviter une erreur lorsque la propriété stuff.value n'est pas définie.

Kevin Schmidt
la source

Réponses:

66

Vous devez définir la valeur null de PropertyPlaceholderConfigurer . Pour l'exemple, j'utilise la chaîne, @nullmais vous pouvez également utiliser la chaîne vide comme nullValue.

<bean id="propertyConfigurer" class="org.springframework.beans.factory.config.PropertyPlaceholderConfigurer">
    <!-- config the location(s) of the properties file(s) here -->
    <property name="nullValue" value="@null" />
</bean>

Vous pouvez maintenant utiliser la chaîne @nullpour représenter la nullvaleur

@Value("${stuff.value:@null}")
private String value;

Remarque: l'espace de noms de contexte ne prend pas en charge la valeur nulle pour le moment. Vous ne pouvez pas utiliser

<context:property-placeholder null-value="@null" ... />

Testé avec Spring 3.1.1

nez
la source
2
Quel est l'équivalent de la configuration Java?
Kumar Sambhav
30
stackoverflow.com/questions/9347929/… mentionne en utilisant $ {some.param: # {null}}, et cela a fonctionné pour moi sans avoir à définir nullValue, semble-t-il que ce soit la valeur par défaut? (Dans une application Spring Boot.)
vorburger
5
Puissance d'utilisation simple de SPEL $ {stuff.value: # {null}} comme suggéré par vorburger et dans stackoverflow.com/questions/16735141
...
semble beaucoup moins de configuration est requise pour les réponses ben3000 et JRichardsz.
Jeff le
193

C'est vraiment vieux, mais vous pouvez utiliser Spring EL maintenant, par exemple

@Value("${stuff.value:#{null}}")

Voir cette question .

ben3000
la source
49

Merci à @vorburger:

@Value("${email.protocol:#{null}}")
String protocol;

définira la valeur de la chaîne à null sans aucune autre configuration.

Kirill Ch
la source
3
travaillé au printemps-boot dernière version 2019: 2.1.7.RELEASE ... start.spring.io
JRichardsz
2

Je donne du crédit à @nosebrain car je ne connaissais pas la "valeur nulle", mais je préfère éviter d'utiliser des valeurs nulles, d'autant plus que c'est difficile à représenter nulldans un fichier de propriétés.

Mais voici une alternative utilisant null sans null-valuepour cela fonctionnera avec n'importe quel espace réservé de propriété.

public class MyObject {

   private String value;

   @Value("${stuff.value:@null}")
   public void setValue(String value) {
      if ("@null".equals(value)) this.value = null;
      else this.value = value;
   }
}

Personnellement, je préfère mon chemin parce que peut-être plus tard vous voudrez stuff.valueêtre une valeur séparée par des virgules ou peut-être enum, le commutateur est plus facile. C'est aussi plus facile à tester unitaire :)

EDIT: basé sur vos commentaires sur l'utilisation des énumérations et mon opinion de ne pas utiliser null.

@Component
public class MyObject {

    @Value("${crap:NOTSET}")
    private Crap crap;

    public enum Crap {
        NOTSET,
        BLAH;
    }
}

Ce qui précède fonctionne très bien pour moi. Vous évitez null. Si vos fichiers de propriétés veulent définir explicitement qu'ils ne veulent pas le gérer, vous le faites ( mais vous n'avez même pas à le spécifier car il sera par défaut NOTSET ).

crap=NOTSET

nullest très mauvais et est différent de NOTSET. Cela signifie que le test de ressort ou d'unité ne l'a pas réglé, c'est pourquoi il y a une différence à mon humble avis. J'utiliserais probablement toujours la notation de setter (exemple précédent) car son test unitaire est plus facile (les variables privées sont difficiles à définir dans un test unitaire).

Adam Gent
la source
La valeur String était un exemple, j'en avais vraiment besoin pour une valeur Enum, où une chaîne vide provoque simplement une erreur de conversion. Avec @null, vous pouvez avoir un null comme "no Enum set", ce dont j'ai besoin.
Kevin Schmidt
Raison de plus pour laquelle je ne recommanderais pas null mais plutôt une énumération qui représente non définie.
Adam Gent
2
Cela nécessiterait de mettre Enum.NOTSET dans tous les fichiers de propriétés (> 30), ce qui semble beaucoup de travail avec presque aucun avantage ...
Kevin Schmidt
Je n'ai pas essayé ça mais en théorie ça ne @Value("${stuff.value:NOTSET}")marcherait pas ?
Adam Gent
Oui, c'est une bonne solution. Malheureusement, je ne peux pas changer l'énumération (dep), je dois donc utiliser null. Sinon, vous avez raison, le NOTSET fonctionnerait.
Kevin Schmidt
0

Au cas où vous auriez besoin d'injecter une chaîne vide (longueur 0) "" comme @Value default - utilisez SPEL (Spring Expression Language) comme suit:

@Value("${index.suffix:#{''}}") 
private String indexSuffix;

# {''} vous donne juste une chaîne vide comme la valeur par défaut de @ Value.

par yl

ylev
la source