So definieren Sie @Value als optional

119

Ich habe folgendes in einer Frühlingsbohne:

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

Der Wert wird korrekt injiziert. Die Variable muss jedoch optional sein. Sie wird als Befehlszeilenparameter übergeben (der dann mithilfe einer SimpleCommandLinePropertySource zum Spring-Kontext hinzugefügt wird ). Dieses Argument ist nicht immer vorhanden.

Ich habe beide folgenden Versuche unternommen, um einen Standardwert bereitzustellen:

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

In jedem Fall wird das Standardargument nach dem Einfügen des Doppelpunkts auch dann verwendet, wenn ein tatsächlicher Wert vorhanden ist. Dies scheint zu überschreiben, was Spring einfügen soll.

Was ist der richtige Weg, um diesen Wert anzugeben ? nicht erforderlich ist?

Vielen Dank

user1052610
quelle
Das ist sehr seltsam ... der Standardwert sollte nur als Standardwert dienen (dh wenn die Eigenschaft nicht definiert ist). Können Sie Ihre Aussage "Standardwert wird auch dann eingefügt, wenn ein tatsächlicher Wert vorhanden ist" (z. B. wenn keine alte kompilierte Klasse vorhanden ist) überprüfen?
Pavel Horal
7
@Value("${some.prop:}")funktioniert für mich. Dies ist die einzige Anmerkung zu dieser Variablen.
Zarathustra
Können Sie Ihre Anwendungskonfiguration veröffentlichen?
Vladimir Vagaytsev
@Autowired (erforderlich = falsch)?
Andrew Scott Evans

Antworten:

179

Wie kann man richtig angeben, dass @Value nicht erforderlich ist?

Arbeiten Sie unter der Annahme, dass Sie mit "nicht erforderlich" meinen null dann ...

Sie haben richtig bemerkt, dass Sie einen Standardwert rechts von einem :Zeichen angeben können. Ihr Beispiel war@Value("${myValue:DEFAULT}") .

Sie sind nicht auf einfache Zeichenfolgen als Standardwerte beschränkt. Sie können SPEL- Ausdrücke verwenden. Ein einfacher SPEL-Ausdruck, der zurückgegeben werden soll, nulllautet:

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

Wenn Sie Java 8 verwenden, können Sie die java.util.OptionalKlasse nutzen. Sie müssen die Variable nur folgendermaßen deklarieren:

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

Dann können Sie überprüfen, ob der Wert besser definiert ist oder nicht:

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

Ich hoffe es hilft!

alonso_50
quelle
4
Nach intelligenter Idee. Es ist keine bewährte Methode, OptionalTypen in Klassenfeldern zu verwenden.
Fırat KÜÇÜK
2
Sie tun dies und es wirft eine NPE. valueist Null.
Aatk
1
@aatk Es scheint, dass das von Ihnen beschriebene Problem mindestens seit 4.3.13 behoben wurde. Ich bekomme keine Probleme mit der beschriebenen Erklärung. Obwohl es besser ist, nur einen nullbaren Wert zu verwenden: blog.joda.org/2015/08/…
Torben
2
"Nach intelligenter Idee. Es ist keine bewährte Methode, optionale Typen in Klassenfeldern zu verwenden." Was ist falsch daran, Optional als Instanzvariable zu verwenden? nur das ist relativ langlebig im Vergleich zu Getter ... und sollte ein solches Feld für die Serialisierung als Transient markiert werden?
Andrey M. Stepanov