@Value
обычно используется для внедрения вынесенных во внешний файл свойств:
@Component
public class MovieRecommender {
private final String catalog;
public MovieRecommender(@Value("${catalog.name}") String catalog) {
this.catalog = catalog;
}
}
@Component
class MovieRecommender(@Value("\${catalog.name}") private val catalog: String)
При следующей конфигурации:
@Configuration
@PropertySource("classpath:application.properties")
public class AppConfig { }
@Configuration
@PropertySource("classpath:application.properties")
class AppConfig
И следующий файл application.properties
:
catalog.name=MovieCatalog
В этом случае параметр и поле catalog
будут равны значению MovieCatalog
.
По умолчанию в Spring предусмотрен гибкий встроенный распознаватель (resolver) значений. Он будет пытаться разрешить значение свойства, но если оно не может быть разрешено, в качестве значения будет внедрено имя свойства (например, ${catalog.name}
). Если вам нужно обеспечить строгий контроль над несуществующими значениями, то следует объявить бин PropertySourcesPlaceholderConfigurer
, как показано в следующем примере:
@Configuration
public class AppConfig {
@Bean
public static PropertySourcesPlaceholderConfigurer propertyPlaceholderConfigurer() {
return new PropertySourcesPlaceholderConfigurer();
}
}
@Configuration
class AppConfig {
@Bean
fun propertyPlaceholderConfigurer() = PropertySourcesPlaceholderConfigurer()
}
PropertySourcesPlaceholderConfigurer
с помощью JavaConfig метод, помеченный аннотацией @Bean
, должен быть статическим
.Использование приведенной выше конфигурации гарантированно приводит к ошибке инициализации Spring, если какой-либо плейсхолдер ${}
не может быть разрешен. Также можно использовать такие методы, как setPlaceholderPrefix
, setPlaceholderSuffix
или setValueSeparator
для настройки плейсхолдеров.
PropertySourcesPlaceholderConfigurer
, который будет получать свойства из файлов application.properties
и application.yml
.Встроенная поддержка преобразователей, предоставляемая Spring, позволяет автоматически выполнять простое преобразование типов (например, в Integer
или int
). Несколько значений, разделенных запятыми, могут быть автоматически преобразованы в массив String
без дополнительной затраты ресурсов.
Можно задать значение по умолчанию следующим образом:
@Component
public class MovieRecommender {
private final String catalog;
public MovieRecommender(@Value("${catalog.name:defaultCatalog}") String catalog) {
this.catalog = catalog;
}
}
@Component
class MovieRecommender(@Value("\${catalog.name:defaultCatalog}") private val catalog: String)
Spring BeanPostProcessor
использует ConversionService
"за кулисами" для обработки процесса преобразования значения String
в аннотации @Value
в целевой тип. Если нужно обеспечить поддержку преобразования для своего собственного кастомного типа, то можно указать свой собственный экземпляр бина ConversionService
, как показано в следующем примере:
@Configuration
public class AppConfig {
@Bean
public ConversionService conversionService() {
DefaultFormattingConversionService conversionService = new DefaultFormattingConversionService();
conversionService.addConverter(new MyCustomConverter());
return conversionService;
}
}
@Configuration
class AppConfig {
@Bean
fun conversionService(): ConversionService {
return DefaultFormattingConversionService().apply {
addConverter(MyCustomConverter())
}
}
}
Если @Value
содержит выражение на SpEL
, значение будет динамически вычисляться во время выполнения, как показано в следующем примере:
@Component
public class MovieRecommender {
private final String catalog;
public MovieRecommender(@Value("#{systemProperties['user.catalog'] + 'Catalog' }") String catalog) {
this.catalog = catalog;
}
}
@Component
class MovieRecommender(
@Value("#{systemProperties['user.catalog'] + 'Catalog' }") private val catalog: String)
SpEL также позволяет использовать более сложные структуры данных:
@Component
public class MovieRecommender {
private final Map<String, Integer> countOfMoviesPerCatalog;
public MovieRecommender(
@Value("#{{'Thriller': 100, 'Comedy': 300}}") Map<String, Integer> countOfMoviesPerCatalog) {
this.countOfMoviesPerCatalog = countOfMoviesPerCatalog;
}
}
@Component
class MovieRecommender(
@Value("#{{'Thriller': 100, 'Comedy': 300}}") private val countOfMoviesPerCatalog: Map<String, Int>)