Una guida rapida a Spring @Value

1. Panoramica

In questo breve tutorial, daremo un'occhiata all'annotazione @Value Spring.

Questa annotazione può essere utilizzata per iniettare valori nei campi nei bean gestiti da Spring e può essere applicata a livello di parametro di campo o costruttore / metodo.

2. Configurazione dell'applicazione

Per descrivere diversi tipi di utilizzo di questa annotazione, è necessario configurare una semplice classe di configurazione dell'applicazione Spring.

Naturalmente, avremo bisogno di un file delle proprietà per definire i valori che vogliamo iniettare con l' annotazione @Value . E quindi, prima dovremo definire una @PropertySource nella nostra classe di configurazione, con il nome del file delle proprietà.

Definiamo il file delle proprietà:

value.from.file=Value got from the file priority=high listOfValues=A,B,C

3. Esempi di utilizzo

Come esempio di base e per lo più inutile, possiamo solo iniettare "valore stringa" dall'annotazione al campo:

@Value("string value") private String stringValue;

L' utilizzo dell'annotazione @PropertySource ci consente di lavorare con i valori dei file delle proprietà con l' annotazione @Value .

Nell'esempio seguente, otteniamo Value ottenuto dal file assegnato al campo:

@Value("${value.from.file}") private String valueFromFile;

Possiamo anche impostare il valore dalle proprietà di sistema con la stessa sintassi.

Supponiamo di aver definito una proprietà di sistema denominata systemValue :

@Value("${systemValue}") private String systemValue;

È possibile fornire valori predefiniti per proprietà che potrebbero non essere definite. Qui, verrà inserito il valore di default :

@Value("${unknown.param:some default}") private String someDefault;

Se la stessa proprietà è definita come proprietà di sistema e nel file delle proprietà, verrà applicata la proprietà di sistema.

Supponiamo di avere una priorità di proprietà definita come proprietà di sistema con il valore Proprietà di sistema e definita come qualcos'altro nel file delle proprietà. Il valore sarebbe Proprietà di sistema :

@Value("${priority}") private String prioritySystemProperty;

A volte, abbiamo bisogno di iniettare un sacco di valori. Sarebbe conveniente definirli come valori separati da virgola per la singola proprietà nel file delle proprietà o come proprietà di sistema e inserirli in un array.

Nella prima sezione, abbiamo definito i valori separati da virgole nella listOfValues del file delle proprietà , quindi i valori dell'array sarebbero ["A", "B", "C"]:

@Value("${listOfValues}") private String[] valuesArray;

4. Esempi avanzati con SpEL

Possiamo anche usare espressioni SpEL per ottenere il valore.

Se abbiamo una proprietà di sistema denominata priorità, il suo valore verrà applicato al campo:

@Value("#{systemProperties['priority']}") private String spelValue;

Se non abbiamo definito la proprietà di sistema, verrà assegnato il valore nullo .

Per evitare ciò, possiamo fornire un valore predefinito nell'espressione SpEL. Otteniamo un valore predefinito per il campo se la proprietà di sistema non è definita:

@Value("#{systemProperties['unknown'] ?: 'some default'}") private String spelSomeDefault;

Inoltre, possiamo utilizzare un valore di campo da altri bean. Supponiamo di avere un bean chiamato someBean con un campo someValue uguale a 10 . Quindi, 10 verranno assegnati al campo:

@Value("#{someBean.someValue}") private Integer someBeanValue;

Possiamo manipolare le proprietà per ottenere un elenco di valori, qui, un elenco di valori di stringa A, B e C:

@Value("#{'${listOfValues}'.split(',')}") private List valuesList;

5. Utilizzo di @Value With Maps

Possiamo anche usare l' annotazione @Value per iniettare una proprietà Map .

Innanzitutto, dobbiamo definire la proprietà nel modulo {key: 'value'} nel nostro file delle proprietà:

valuesMap={key1: '1', key2: '2', key3: '3'}

Notare che i valori nella mappa devono essere racchiusi tra virgolette singole.

Ora possiamo inserire questo valore dal file delle proprietà come mappa :

@Value("#{${valuesMap}}") private Map valuesMap;

Se abbiamo bisogno di ottenere il valore di una chiave specifica nella mappa , tutto ciò che dobbiamo fare è aggiungere il nome della chiave nell'espressione :

@Value("#{${valuesMap}.key1}") private Integer valuesMapKey1;

Se non siamo sicuri che la mappa contenga una determinata chiave, dovremmo scegliere un'espressione più sicura che non genererà un'eccezione ma impostare il valore su null quando la chiave non viene trovata:

@Value("#{${valuesMap}['unknownKey']}") private Integer unknownMapKey;

Possiamo anche impostare valori predefiniti per le proprietà o le chiavi che potrebbero non esistere :

@Value("#{${unknownMap : {key1: '1', key2: '2'}}}") private Map unknownMap; @Value("#{${valuesMap}['unknownKey'] ?: 5}") private Integer unknownMapKeyWithDefaultValue;

Le voci della mappa possono anche essere filtrate prima dell'iniezione.

Supponiamo di dover ottenere solo quelle voci i cui valori sono maggiori di uno:

@Value("#{${valuesMap}.?[value>'1']}") private Map valuesMapFiltered;

Possiamo anche usare l' annotazione @Value per inserire tutte le proprietà di sistema correnti :

@Value("#{systemProperties}") private Map systemPropertiesMap;

6. Utilizzo di @Value con 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

In questo articolo abbiamo esaminato le varie possibilità di utilizzo dell'annotazione @Value con proprietà semplici definite nel file, con proprietà di sistema e con proprietà calcolate con espressioni SpEL.

Come sempre, l'applicazione di esempio è disponibile nel progetto GitHub.