Comment définir @Value comme facultatif

119

J'ai ce qui suit dans un haricot de printemps:

@Value("${myValue}")
private String value;

La valeur est correctement injectée. Cependant, la variable doit être facultative, elle est transmise en tant que paramètre de ligne de commande (qui est ensuite ajouté au contexte Spring à l'aide d'un SimpleCommandLinePropertySource ), et cet argument n'existera pas toujours.

J'ai essayé les deux méthodes suivantes afin de fournir une valeur par défaut:

@Value("${myValue:}")
@Value("${myValue:DEFAULT}")

mais dans chaque cas, l'argument par défaut après les deux-points est injecté même s'il y a une valeur réelle - cela semble remplacer ce que Spring devrait injecter.

Quelle est la manière correcte de spécifier que @Value n'est pas obligatoire?

Merci

user1052610
la source
C'est très étrange ... la valeur par défaut ne devrait agir que comme valeur par défaut (c'est-à-dire lorsque la propriété n'est pas définie). Pouvez-vous vérifier votre déclaration "la valeur par défaut est injectée même s'il y a une valeur réelle" (par exemple s'il n'y a pas une ancienne classe compilée)?
Pavel Horal
7
@Value("${some.prop:}")fonctionne pour moi. C'est la seule annotation sur cette variable.
Zarathustra
Pouvez-vous publier la configuration de votre application?
Vladimir Vagaytsev
@Autowired (obligatoire = faux)?
Andrew Scott Evans

Réponses:

179

Quelle est la manière correcte de spécifier que @Value n'est pas obligatoire?

En partant du principe que par `` non requis '' vous entendez nullalors ...

Vous avez correctement noté que vous pouvez fournir une valeur par défaut à droite d'un :caractère. Votre exemple était @Value("${myValue:DEFAULT}").

Vous n'êtes pas limité aux chaînes simples comme valeurs par défaut. Vous pouvez utiliser des expressions SPEL , et une expression SPEL simple à renvoyer nullest:

@Value("${myValue:#{null}}")
Andy Brown
la source
49

Si vous utilisez Java 8, vous pouvez profiter de sa java.util.Optionalclasse. Il vous suffit de déclarer la variable de cette façon:

@Value("${myValue:#{null}}")
private Optional<String> value;

Ensuite, vous pouvez vérifier si la valeur est définie ou non d'une manière plus agréable:

if (value.isPresent()) {
    // do something cool
}

J'espère que ça aide!

alonso_50
la source
4
Selon l'idée intelliJ. Il n'est pas recommandé d'utiliser des Optionaltypes dans les champs de classe.
Fırat KÜÇÜK
2
Vous faites cela et il jette un NPE. valueest nul.
aatk
1
@aatk Il semble que le problème que vous décrivez a été résolu au moins depuis la version 4.3.13. Je n'ai aucun problème à utiliser la déclaration décrite. Bien qu'il soit préférable d'utiliser simplement une valeur nullable
Torben
2
"Selon l'idée intelliJ. Il n'est pas recommandé d'utiliser des types facultatifs dans les champs de classe." qu'est-ce qui ne va pas dans l'utilisation de Optional comme variable d'instance? seulement cela est relativement long par rapport à lorsqu'il est utilisé dans les getters ... et un tel champ doit être marqué Transient pour la sérialisation?
Andrey M. Stepanov