191

I have the following in a Spring bean:

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

The value is correctly injected. However, the variable needs to be optional, it is passed in as a command line parameter (which is then added to the Spring context using a SimpleCommandLinePropertySource), and this argument will not always exist.

I have tried both the following in order to provide a default value:

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

but in each case, the default argument after the colon is injected even when there is an actual value - this appears override what Spring should inject.

What is the correct way to specify that @Value is not required?

Thanks

4
  • That is very strange... the default value should act as an default value only (i.e. when the property is not defined). Can you double check your statement "default value is injected even when there is an actual value" (e.g. if there is not an old compiled class)? Commented Apr 28, 2014 at 18:12
  • 8
    @Value("${some.prop:}") does work for me. That is the only Annotation on that variable. Commented Jun 24, 2014 at 9:54
  • Can you post your application config? Commented May 20, 2016 at 13:47
  • @Autowired(required =false)? Commented Mar 21, 2017 at 22:51

4 Answers 4

270

What is the correct way to specify that @Value is not required?

Working on the assumption that by 'not required' you mean null then...

You have correctly noted that you can supply a default value to the right of a : character. Your example was @Value("${myValue:DEFAULT}").

You are not limited to plain strings as default values. You can use SPEL expressions, and a simple SPEL expression to return null is:

@Value("${myValue:#{null}}")
3
  • 1
    I have the same problem as the original poster when using Spring 5.0.12. Using the construction with :#{null} doesn't help, it makes it ignore the actual property value assigned in the same way.
    – Stefan L
    Commented Sep 22, 2020 at 11:50
  • Update: A small hello-world type spring non-boot application based on annotations has working :default handling, Properties are then also programatically accessible from the Environment if injected. Must be some extra configuration/customization causing this.
    – Stefan L
    Commented Sep 23, 2020 at 7:42
  • confusing, what is the myValue relates to in this case why this word? is it the same as the variable name or what, should have a complete example.
    – Mobigital
    Commented Jun 23, 2021 at 20:24
92

If you are using Java 8, you can take advantage of its java.util.Optional class. You just have to declare the variable following this way:

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

Then, you can check whether the value is defined or not in a nicer way:

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

Hope it helps!

4
  • 9
    According to intelliJ idea. It's not a best practice to use Optional types in class fields. Commented Aug 30, 2018 at 12:31
  • 5
    You do this and it throws a NPE. value is null.
    – aatk
    Commented Dec 7, 2018 at 14:51
  • 1
    @aatk It seems that the issue you describe has been fixed at least since 4.3.13. I get no trouble using the described declaration. Though it's better to just use a nullable value: blog.joda.org/2015/08/…
    – Torben
    Commented Apr 2, 2019 at 11:22
  • 3
    "According to intelliJ idea. It's not a best practice to use Optional types in class fields." what is wrong about using Optional as instance variable? only that is relatively long lived compared to when used in getters... and such field should be marked Transient for serialization? Commented May 16, 2019 at 14:59
7

If you want to make the configuration property optional just pass an empty string like this:

@Value("${app.optional.value:}")
3

I guess you are you using multiple context:property-placeholder/ declarations?

If so, this is a known issue since 2012, but not fixed, apparently due to both lack of interest and no clean way of fixing it. See https://github.com/spring-projects/spring-framework/issues/14623 for discussion and some ways to work around it. It's explained in an understandable way by http://www.michelschudel.nl/wp/2017/01/25/beware-of-multiple-spring-propertyplaceholderconfigurers-and-default-values/

1
  • Thank you - this explains why I was getting default value even when the property was defined.
    – Faustas
    Commented Dec 16, 2020 at 17:15

Not the answer you're looking for? Browse other questions tagged or ask your own question.