Using @Value
@Value is typically used to inject externalized properties:
- 
Java
 
@Component
public class MovieRecommender {
    private final String catalog;
    public MovieRecommender(@Value("${catalog.name}") String catalog) {
        this.catalog = catalog;
    }
}
With the following configuration:
- 
Java
 
@Configuration
@PropertySource("classpath:application.properties")
public class AppConfig {
}
And the following application.properties file:
catalog.name=MovieCatalog
In that case, the catalog parameter and field will be equal to the MovieCatalog value.
A default lenient embedded value resolver is provided by Infra. It will try to resolve the
property value and if it cannot be resolved, the property name (for example ${catalog.name})
will be injected as the value. If you want to maintain strict control over nonexistent
values, you should declare a PropertySourcesPlaceholderConfigurer bean, as the following
example shows:
- 
Java
 
@Configuration
public class AppConfig {
  @Bean
  public static PropertySourcesPlaceholderConfigurer propertyPlaceholderConfigurer() {
    return new PropertySourcesPlaceholderConfigurer();
  }
}
When configuring a PropertySourcesPlaceholderConfigurer using JavaConfig, the
@Bean method must be static.
 | 
Using the above configuration ensures Infra initialization failure if any ${}
placeholder could not be resolved. It is also possible to use methods like
setPlaceholderPrefix, setPlaceholderSuffix, setValueSeparator, or
setEscapeCharacter to customize placeholders.
Infra App configures by default a PropertySourcesPlaceholderConfigurer bean that
will get properties from application.properties and application.yml files.
 | 
Built-in converter support provided by Infra allows simple type conversion (to Integer
or int for example) to be automatically handled. Multiple comma-separated values can be
automatically converted to String array without extra effort.
It is possible to provide a default value as following:
- 
Java
 
@Component
public class MovieRecommender {
  private final String catalog;
  public MovieRecommender(@Value("${catalog.name:defaultCatalog}") String catalog) {
    this.catalog = catalog;
  }
}
A Infra BeanPostProcessor uses a ConversionService behind the scenes to handle the
process for converting the String value in @Value to the target type. If you want to
provide conversion support for your own custom type, you can provide your own
ConversionService bean instance as the following example shows:
- 
Java
 
@Configuration
public class AppConfig {
  @Bean
  public ConversionService conversionService() {
    DefaultFormattingConversionService conversionService = new DefaultFormattingConversionService();
    conversionService.addConverter(new MyCustomConverter());
    return conversionService;
  }
}
When @Value contains a SpEL expression the value will be dynamically
computed at runtime as the following example shows:
- 
Java
 
@Component
public class MovieRecommender {
  private final String catalog;
  public MovieRecommender(@Value("#{systemProperties['user.catalog'] + 'Catalog' }") String catalog) {
    this.catalog = catalog;
  }
}
SpEL also enables the use of more complex data structures:
- 
Java
 
@Component
public class MovieRecommender {
  private final Map<String, Integer> countOfMoviesPerCatalog;
  public MovieRecommender(@Value("#{{'Thriller': 100, 'Comedy': 300}}") Map<String, Integer> countOfMoviesPerCatalog) {
    this.countOfMoviesPerCatalog = countOfMoviesPerCatalog;
  }
}