${...} заполнители в аннотации @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")@ComponentScanclass ApplicationConfig { @Bean public static PropertySourcesPlaceholderConfigurer placeholderConfigurer() { return new PropertySourcesPlaceholderConfigurer(); }} |
Другой способ добавить источник свойства в конфигуратор — вызвать его метод setLocation :
|
01
02
03
04
05
06
07
08
09
10
11
12
|
@Configuration@ComponentScanclass 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 textmy.int.property=42my.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
|
@Beanpublic 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,5my.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 localemy.localDate.property=9/28/15my.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 299my.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 . |