Friday, April 22, 2016

Spring Gotchas - Default value expressions not working for @Value

The @Value annotation is very useful in Spring, and the default value syntax also comes in handy.  However, when working on a new project and setting up your initial configuration, or when setting up a test fixture bean configuration, you may encounter situations where the default value syntax simply doesn't work.   For example:

    @Value("${some.setting:8}")
    private int mySetting;

So here, we wanted a default value of 8 if the some.settings property is not found. Simple enough, but still... you end up getting this kind of error:

org.springframework.beans.factory.BeanCreationException: Error creating bean with name '.... blah blah blah ...' 
Caused by: org.springframework.beans.factory.BeanCreationException: Could not autowire field: private int com.foo.MyBean.mySetting; nested exception is org.springframework.beans.TypeMismatchException: Failed to convert value of type [java.lang.String] to required type [int]; nested exception is java.lang.NumberFormatException: For input string: "${some.setting:8}"
 ... 
Caused by: org.springframework.beans.TypeMismatchException: Failed to convert value of type [java.lang.String] to required type [int]; nested exception is java.lang.NumberFormatException: For input string: "${some.setting:8}"
 ...
Caused by: java.lang.NumberFormatException: For input string: "${some.setting:8}"
This means that Spring does not know how to interpret the default value expression. To enable the Spring Expression Language in @Value just add PropertySourcesPlaceholderConfigurer to the configuration. In Java annotations:
@Configuration
public class MyConfig
{
    ...

    @Bean
    public static PropertySourcesPlaceholderConfigurer getPropertySourcesPlaceholderConfigurer()
    {
        return new PropertySourcesPlaceholderConfigurer();
    }

    ...
}
In XML, this is usually not a problem because you've got:
  
<context:property-placeholder location="classpath:defaults.properties"/>

Thanks to MyKong for the solution!
See http://www.mkyong.com/spring3/spring-value-default-value/