${...}
заполнители в аннотации @Value
используются для доступа к свойствам, зарегистрированным в @PropertySource
. Это чрезвычайно полезно с @Configuration
компонентами @Configuration
в приложениях Spring, но не только. Чтобы убедиться, что это возможно, PropertySourcesPlaceholderConfigurer
должен присутствовать во всех контекстах приложения, для которых требуется разрешение заполнителей.
В этом посте вы узнаете, как настроить разрешение заполнителей в приложениях Spring 4 и внедрить различные типы объектов с @Value
аннотации @Value
, включая JSR-310 Date-Time, JSR-354 Money & Currency или java.util.Optional
.
Регистрация PropertySourcesPlaceholderConfigurer
В приложениях Spring с конфигурацией no-xml статический компонент PropertySourcesPlaceholderConfigurer
должен быть зарегистрирован во всех контекстах приложения.
Чтобы зарегистрировать PropertySourcesPlaceholderConfigurer
просто добавьте статический бин того же типа в конфигурацию вместе с источниками свойств, к которым вы хотите иметь доступ. Для импорта нескольких источников свойств используйте аннотацию @PropertySources
(до Java 8) или несколько аннотаций @PropertySource
(Java 8).
01
02
03
04
05
06
07
08
09
10
11
|
@Configuration @PropertySource ( "classpath:application.properties" ) @ComponentScan class ApplicationConfig { @Bean public static PropertySourcesPlaceholderConfigurer placeholderConfigurer() { return new PropertySourcesPlaceholderConfigurer(); } } |
Другой способ добавить источник свойства в конфигуратор — вызвать его метод setLocation
:
01
02
03
04
05
06
07
08
09
10
11
12
|
@Configuration @ComponentScan class ApplicationConfig { @Bean public static PropertySourcesPlaceholderConfigurer placeholderConfigurer() { PropertySourcesPlaceholderConfigurer c = new PropertySourcesPlaceholderConfigurer(); c.setLocation( new ClassPathResource( "application.properties" )); return c; } } |
Внедрение простых свойств
Теперь вы можете легко получить доступ к свойствам с @Value
аннотации @Value
и заполнителей:
1
2
3
4
5
6
|
@Value ( "${my.string.property}" ) private String stringProperty; @Value ( "${my.int.property}" ) private int intProperty; @Value ( "${my.boolean.property}" ) private boolean boolProperty; |
Свойства определены в файле application.properties
:
1
2
3
|
my.string.property=Some text my. int .property= 42 my. boolean .property= true |
Если свойство не может быть разрешено, вы получите исключение:
1
|
java.lang.IllegalArgumentException: Could not resolve placeholder 'placeholder' in string value "${placeholder}" |
Игнорирование неразрешимых заполнителей
Если вы хотите автоматически игнорировать все неразрешимые заполнители, установите соответствующий флаг конфигуратора:
1
2
3
|
PropertySourcesPlaceholderConfigurer c = new PropertySourcesPlaceholderConfigurer(); c.setIgnoreUnresolvablePlaceholders( true ); |
Значения по умолчанию
Значения по умолчанию могут быть предоставлены со следующим синтаксисом:
1
2
|
@Value ( "${my.string.property:Sample}" ) private String stringProperty; |
Также поддерживается пустое значение по умолчанию, что приводит к пустой stringProperty
:
1
2
|
@Value ( "${my.string.property:}" ) private String stringProperty; |
Нулевые значения
Если вы хотите, чтобы пустые значения обрабатывались как null
вы можете установить свойство nullValue
в конфигураторе следующим образом:
1
2
|
PropertySourcesPlaceholderConfigurer c = new PropertySourcesPlaceholderConfigurer(); c.setNullValue( "" ); |
Это может быть полезно, особенно когда я работаю с java.util.Optional
(см. Ниже).
Внедрение непростых свойств
Чтобы внедрить сложные свойства с @Value
аннотации @Value
, необходимо сделать доступным Spring ConversionService
в контексте приложения. Регистрация сервиса конвертации по умолчанию дает возможность вводить списки, массивы и другие конвертируемые типы. Обычно, в контексте сервлета Spring, ConversionService
будет зарегистрирован (например, через @EnableWebMvc
), но для ручной регистрации вы можете использовать следующий код. Обратите внимание, что имя bean-компонента должно быть conversionService
:
1
2
3
4
|
@Bean public static ConversionService conversionService() { return new DefaultFormattingConversionService(); } |
DefaultFormattingConversionService
поддерживает все распространенные конвертеры и форматеры, включая форматеры для JSR-354 Money & Currency, JSR-310 Date-Time и / или Joda-Time.
Инъекционный список / массивы
Чтобы добавить список или массив из свойства, вы определяете значение свойства с помощью строки, разделенной запятыми:
1
2
|
my.intList.property= 1 , 2 , 3 , 4 , 5 my.stringArray.property= 1 , 2 , 3 , 4 , 5 |
И вводить их так:
1
2
3
4
5
|
@Value ( "${my.intList.property}" ) private List<Integer> intList; @Value ( "${my.stringArray.property}" ) private List<Integer> stringArray; |
Инъекция java.util.Optional
Дополнительный Java 8 дает прекрасную возможность работать с дополнительными свойствами. Хитрость с внедрением Optional
с @Value
заключается в том, что значения свойств должны быть проанализированы с null
значением, и для достижения этого свойства nullValue
в конфигураторе должно быть установлено соответственно (как показано ранее).
1
2
|
@Value ( "${my.optional.property:}" ) private Optional<String> optional; |
Если свойство my.optional.property
, optional
будет содержать Optional.empty
и поэтому его можно использовать в коде:
1
2
3
|
if (optional.isPresent()) { // do something cool } |
Внедрение типов java.time
Зарегистрированные ConversionService
содержит форматеры для даты и времени JSR-310. Ниже приведены примеры для LocalDate
и LocalDateTime
в текущей локали:
1
2
3
|
# format for en_US locale my.localDate.property= 9 / 28 / 15 my.localDateTime.property= 9 / 28 / 15 10 : 05 PM |
1
2
3
4
|
@Value ( "${my.localDate.property}" ) private LocalDate localDate; @Value ( "${my.localDateTime.property}" ) private LocalDateTime localDateTime; |
Внедрение javax.money
типов
Как только javax.money
окажется на пути к классам, вы можете ввести MonetaryAmount
и CurrencyUnit
:
1
2
|
my.monetaryAmount.property=USD 299 my.currencyUnit.property=USD |
1
2
3
4
|
@Value ( "${my.monetaryAmount.property}" ) private MonetaryAmount monetaryAmount; @Value ( "${my.currencyUnit.property}" ) private CurrencyUnit currencyUnit; |
Внедрение пользовательских типов
С ConversionService
относительно легко зарегистрировать пользовательские конвертеры. В приведенном ниже примере объект java.util.Pattern
будет создан из строкового значения: my.pattern.property=[0-9].*
. Для этого нам нужно добавить пользовательский конвертированный:
1
2
3
|
DefaultFormattingConversionService cs = new DefaultFormattingConversionService(); cs.addConverter(String. class , Pattern. class , (Converter<String, Pattern>) Pattern::compile); |
Теперь свойство может быть введено, как показано ниже:
1
2
|
@Value ( "${my.pattern.property}" ) private Pattern pattern; |
Дополнительно — доступ к свойствам Spring в представлении Thymeleaf
Если вы работаете с Thymeleaf и хотите получить доступ к свойствам, зарегистрированным в среде Spring (с PropertySourcesPlaceholderConfigurer
или просто с @PropertySource
), вы можете использовать способность Thymeleaf для доступа к свойствам Spring Beans с использованием синтаксиса SpringEL: $ {@ myBean.doSomething ()}. Все свойства доступны через интерфейс Environment
, поэтому получить доступ к нему в Thymeleaf так же просто, как вызвать его метод getProperty
:
1
2
3
|
<div th:fragment= "footer" th:align= "center" > <span th:text= "${@environment.getProperty('app.version')}" ></span> </div> |
Закрытие заметки
Вы можете найти простое использование аннотации @Value
и PropertySourcesPlaceholderConfigurer
в @Value
моего Spring-архетипа здесь: https://github.com/kolorobot/spring-mvc-quickstart-archetype .
Если вы работаете с Spring Boot, вы можете прочитать о свойствах безопасной конфигурации типов: http://docs.spring.io/spring-boot/docs/current/reference/htmlsingle/#boot-features-external-config- типизированная-конфигурация-свойство
Ссылка: | Поддержка заполнителей в аннотациях Value весной от нашего партнера JCG Рафаля Боровца в блоге Codeleak.pl . |