Using Value

Uso de @Value

@Value se utiliza normalmente para inyectar propiedades externalizadas:

@Component
public class MovieRecommender {

	private final String catalog;

	public MovieRecommender(@Value("${catalog.name}") String catalog) {
		this.catalog = catalog;
	}
}

Con la siguiente configuración:

@Configuration
@PropertySource("classpath:application.properties")
public class AppConfig {
}

Y el siguiente archivo application.properties:

catalog.name=MovieCatalog

En ese caso, el parámetro y el campo catalog tendrán el valor MovieCatalog.

Spring proporciona un resolvedor de valores incrustados predeterminado y permisivo. Intenta resolver el valor de la propiedad y, si no puede hacerlo, inyecta el nombre de la propiedad —por ejemplo, ${catalog.name}— como valor.

Si quieres mantener un control estricto sobre valores inexistentes, debes declarar un bean PropertySourcesPlaceholderConfigurer, como muestra el siguiente ejemplo:

@Configuration
public class AppConfig {

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

Al configurar un PropertySourcesPlaceholderConfigurer mediante JavaConfig, el método @Bean debe ser static.

La configuración anterior hace que la inicialización de Spring falle si no se puede resolver cualquier marcador de posición ${}. También puedes utilizar métodos como setPlaceholderPrefix(), setPlaceholderSuffix(), setValueSeparator() o setEscapeCharacter() para personalizar la sintaxis de los marcadores de posición.

Además, puedes cambiar o deshabilitar globalmente el carácter de escape predeterminado estableciendo la propiedad spring.placeholder.escapeCharacter.default mediante una propiedad del sistema de la JVM o mediante el mecanismo SpringProperties.

Spring Boot configura de forma predeterminada un bean PropertySourcesPlaceholderConfigurer que obtiene propiedades de los archivos application.properties y application.yml.

El soporte de conversión integrado de Spring permite gestionar automáticamente conversiones sencillas de tipos —por ejemplo, a Integer o int—. Los valores múltiples separados por comas también se pueden convertir automáticamente en un array de String sin esfuerzo adicional.

Puedes proporcionar un valor predeterminado de la siguiente forma:

@Component
public class MovieRecommender {

	private final String catalog;

	public MovieRecommender(@Value("${catalog.name:defaultCatalog}") String catalog) {
		this.catalog = catalog;
	}
}

Un BeanPostProcessor de Spring utiliza internamente un ConversionService para convertir el valor String de @Value al tipo de destino.

Si quieres proporcionar soporte de conversión para un tipo personalizado, puedes declarar tu propia instancia de ConversionService, como muestra el siguiente ejemplo:

@Configuration
public class AppConfig {

	@Bean
	public ConversionService conversionService() {
		DefaultFormattingConversionService conversionService =
				new DefaultFormattingConversionService();
		conversionService.addConverter(new MyCustomConverter());
		return conversionService;
	}
}

Cuando @Value contiene una expresión SpEL, el valor se calcula dinámicamente en tiempo de ejecución, como muestra el siguiente ejemplo:

@Component
public class MovieRecommender {

	private final String catalog;

	public MovieRecommender(
			@Value("#{systemProperties['user.catalog'] + 'Catalog'}") String catalog) {
		this.catalog = catalog;
	}
}

SpEL también permite utilizar estructuras de datos más complejas:

@Component
public class MovieRecommender {

	private final Map<String, Integer> countOfMoviesPerCatalog;

	public MovieRecommender(
			@Value("#{{'Thriller': 100, 'Comedy': 300}}")
			Map<String, Integer> countOfMoviesPerCatalog) {
		this.countOfMoviesPerCatalog = countOfMoviesPerCatalog;
	}
}