1. Обзор
В этом кратком руководстве мы рассмотрим аннотацию @Value
Spring.
Эту аннотацию можно использовать для ввода значений в поля в компонентах, управляемых Spring, и ее можно применять на уровне параметров поля или конструктора/метода.
2. Настройка приложения
Чтобы описать различные виды использования этой аннотации, нам нужно настроить простой класс конфигурации приложения Spring.
Естественно, нам понадобится файл свойств для определения значений, которые мы хотим внедрить с помощью аннотации @Value
. Итак, сначала нам нужно определить @PropertySource
в нашем классе конфигурации — с именем файла свойств.
Давайте определим файл свойств:
value.from.file=Value got from the file
priority=high
listOfValues=A,B,C
3. Примеры использования
В качестве базового и в основном бесполезного примера мы можем ввести только «строковое значение» из аннотации в поле:
@Value("string value")
private String stringValue;
Использование аннотации @PropertySource
позволяет нам работать со значениями из файлов свойств с аннотацией @Value
.
В следующем примере мы получаем значение, полученное из файла,
назначенного полю:
@Value("${value.from.file}")
private String valueFromFile;
Мы также можем установить значение из системных свойств с тем же синтаксисом.
Предположим, что мы определили системное свойство с именем systemValue
:
@Value("${systemValue}")
private String systemValue;
Для свойств, которые могут не быть определены, могут быть предоставлены значения по умолчанию. Здесь будет введено значение по умолчанию :
@Value("${unknown.param:some default}")
private String someDefault;
Если одно и то же свойство определено как системное свойство и в файле свойств, то будет применено системное свойство.
Предположим, у нас есть приоритет
свойства, определенный как системное свойство со значением свойства System
и определенный как что-то еще в файле свойств. Значение будет системным свойством
:
@Value("${priority}")
private String prioritySystemProperty;
Иногда нам нужно ввести кучу значений. Было бы удобно определить их как разделенные запятыми значения для одного свойства в файле свойств или как системное свойство и внедрить в массив.
В первом разделе мы определили значения, разделенные запятыми, в listOfValues
файла свойств ,
поэтому значения массива будут ["A", "B", "C"]:
@Value("${listOfValues}")
private String[] valuesArray;
4. Продвинутые примеры с SpEL
Мы также можем использовать выражения SpEL для получения значения.
Если у нас есть системное свойство с именем priority,
то его значение будет применено к полю:
@Value("#{systemProperties['priority']}")
private String spelValue;
Если мы не определили системное свойство, то будет присвоено нулевое значение.
Чтобы предотвратить это, мы можем указать значение по умолчанию в выражении SpEL. Мы получаем какое-то значение по умолчанию
для поля, если системное свойство не определено:
@Value("#{systemProperties['unknown'] ?: 'some default'}")
private String spelSomeDefault;
Кроме того, мы можем использовать значение поля из других компонентов. Предположим, у нас есть bean-компонент с именем someBean
с полем someValue,
равным 10
. Тогда 10
будет присвоено полю:
@Value("#{someBean.someValue}")
private Integer someBeanValue;
Мы можем манипулировать свойствами, чтобы получить список
значений, здесь список строковых значений A, B и C:
@Value("#{'${listOfValues}'.split(',')}")
private List<String> valuesList;
5. Использование @Value
с картами
Мы также можем использовать аннотацию @Value
для внедрения свойства Map .
Во-первых, нам нужно определить свойство в форме {key: 'value' }
в нашем файле свойств:
valuesMap={key1: '1', key2: '2', key3: '3'}
Обратите внимание, что значения на карте
должны быть заключены в одинарные кавычки.
Теперь мы можем внедрить это значение из файла свойств как Map
:
@Value("#{${valuesMap}}")
private Map<String, Integer> valuesMap;
Если нам нужно получить значение определенного ключа в Map
, все, что нам нужно сделать, это добавить имя ключа в выражение :
@Value("#{${valuesMap}.key1}")
private Integer valuesMapKey1;
Если мы не уверены, содержит ли Map
определенный ключ, мы должны выбрать более безопасное выражение, которое не будет генерировать исключение, а установит значение null
, если ключ не найден:
@Value("#{${valuesMap}['unknownKey']}")
private Integer unknownMapKey;
Мы также можем установить значения по умолчанию для свойств или ключей, которые могут не существовать :
@Value("#{${unknownMap : {key1: '1', key2: '2'}}}")
private Map<String, Integer> unknownMap;
@Value("#{${valuesMap}['unknownKey'] ?: 5}")
private Integer unknownMapKeyWithDefaultValue;
Записи карты
также могут быть отфильтрованы перед внедрением.
Предположим, нам нужно получить только те записи, значения которых больше единицы:
@Value("#{${valuesMap}.?[value>'1']}")
private Map<String, Integer> valuesMapFiltered;
Мы также можем использовать аннотацию @Value для
внедрения всех текущих свойств системы :
@Value("#{systemProperties}")
private Map<String, String> systemPropertiesMap;
6. Использование @Value
с внедрением конструктора
Когда мы используем аннотацию @Value
, мы не ограничиваемся внедрением поля. Мы также можем использовать его вместе с внедрением конструктора.
Давайте посмотрим это на практике:
@Component
@PropertySource("classpath:values.properties")
public class PriorityProvider {
private String priority;
@Autowired
public PriorityProvider(@Value("${priority:normal}") String priority) {
this.priority = priority;
}
// standard getter
}
В приведенном выше примере мы вводим приоритет
непосредственно в наш конструктор PriorityProvider
.
Обратите внимание, что мы также предоставляем значение по умолчанию на случай, если свойство не будет найдено.
7. Использование @Value
с внедрением сеттера
По аналогии с внедрением конструктора мы также можем использовать @Value
с внедрением сеттера.
Давайте взглянем:
@Component
@PropertySource("classpath:values.properties")
public class CollectionProvider {
private List<String> values = new ArrayList<>();
@Autowired
public void setValues(@Value("#{'${listOfValues}'.split(',')}") List<String> values) {
this.values.addAll(values);
}
// standard getter
}
Мы используем выражение SpEL для ввода списка значений в метод setValues
.
8. Заключение
В этой статье мы рассмотрели различные возможности использования аннотации @Value
с простыми свойствами, определенными в файле, с системными свойствами и со свойствами, вычисляемыми с помощью выражений SpEL.
Как всегда, пример приложения доступен на проекте GitHub .