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("${value.from.file}") private String valueFromFile;
Можем също да зададем стойността от системните свойства със същия синтаксис.
Да приемем, че сме дефинирали системно свойство, наречено systemValue :
@Value("${systemValue}") private String systemValue;
Стойности по подразбиране могат да бъдат предоставени за свойства, които може да не са дефинирани. Тук ще се инжектира стойността по подразбиране :
@Value("${unknown.param:some default}") private String someDefault;
Ако същото свойство е дефинирано като системно свойство и във файла със свойствата, тогава системното свойство ще бъде приложено.
Да предположим, че имаме приоритет на свойството, дефиниран като системно свойство със стойността System свойство и дефинирано като нещо друго във файла със свойствата. Стойността ще бъде свойство System :
@Value("${priority}") private String prioritySystemProperty;
Понякога трябва да инжектираме куп ценности. Би било удобно да ги дефинирате като разделени със запетая стойности за единичното свойство във файла със свойствата или като системно свойство и да ги инжектирате в масив.
В първия раздел дефинирахме стойности, разделени със запетая, в listOfValues на файла със свойства , така че стойностите на масива ще бъдат [„A“, „B“, „C“]:
@Value("${listOfValues}") private String[] valuesArray;
4. Разширени примери със SpEL
Също така можем да използваме изрази SpEL, за да получим стойността.
Ако имаме системно свойство с име приоритет, тогава неговата стойност ще бъде приложена към полето:
@Value("#{systemProperties['priority']}") private String spelValue;
Ако не сме дефинирали системното свойство, тогава ще бъде присвоена нулевата стойност.
За да предотвратим това, можем да предоставим стойност по подразбиране в израза SpEL. Получаваме някаква стойност по подразбиране за полето, ако системното свойство не е дефинирано:
@Value("#{systemProperties['unknown'] ?: 'some default'}") private String spelSomeDefault;
Освен това можем да използваме стойност на поле от други зърна. Да предположим, че имаме боб с име someBean с поле someValue, равно на 10 . След това на полето ще бъдат зададени 10 :
@Value("#{someBean.someValue}") private Integer someBeanValue;
We can manipulate properties to get a List of values, here, a list of string values A, B, and C:
@Value("#{'${listOfValues}'.split(',')}") private List valuesList;
5. Using @Value With Maps
We can also use the @Value annotation to inject a Map property.
First, we'll need to define the property in the {key: ‘value' } form in our properties file:
valuesMap={key1: '1', key2: '2', key3: '3'}
Note that the values in the Map must be in single quotes.
Now we can inject this value from the property file as a Map:
@Value("#{${valuesMap}}") private Map valuesMap;
If we need to get the value of a specific key in the Map, all we have to do is add the key's name in the expression:
@Value("#{${valuesMap}.key1}") private Integer valuesMapKey1;
If we're not sure whether the Map contains a certain key, we should choose a safer expression that will not throw an exception but set the value to null when the key is not found:
@Value("#{${valuesMap}['unknownKey']}") private Integer unknownMapKey;
We can also set default values for the properties or keys that might not exist:
@Value("#{${unknownMap : {key1: '1', key2: '2'}}}") private Map unknownMap; @Value("#{${valuesMap}['unknownKey'] ?: 5}") private Integer unknownMapKeyWithDefaultValue;
Map entries can also be filtered before injection.
Let's assume we need to get only those entries whose values are greater than one:
@Value("#{${valuesMap}.?[value>'1']}") private Map valuesMapFiltered;
We can also use the @Value annotation to inject all current system properties:
@Value("#{systemProperties}") private Map systemPropertiesMap;
6. Using @Value With Constructor Injection
When we use the @Value annotation, we're not limited to a field injection. We can also use it together with constructor injection.
Let's see this in practice:
@Component @PropertySource("classpath:values.properties") public class PriorityProvider { private String priority; @Autowired public PriorityProvider(@Value("${priority:normal}") String priority) { this.priority = priority; } // standard getter }
In the above example, we inject a priority directly into our PriorityProvider‘s constructor.
Note that we also provide a default value in case the property isn't found.
7. Using @Value With Setter Injection
Analogous to the constructor injection, we can also use @Value with setter injection.
Let's take a look:
@Component @PropertySource("classpath:values.properties") public class CollectionProvider { private List values = new ArrayList(); @Autowired public void setValues(@Value("#{'${listOfValues}'.split(',')}") List values) { this.values.addAll(values); } // standard getter }
We use the SpEL expression to inject a list of values into the setValues method.
8. Conclusion
В тази статия разгледахме различните възможности за използване на анотацията @Value с прости свойства, дефинирани във файла, със системни свойства и със свойства, изчислени с изрази SpEL.
Както винаги, примерното приложение е налично в проекта GitHub.