Una guía rápida de Spring @Value

1. Información general

En este tutorial rápido, vamos a echar un vistazo a la anotación de @Value Spring.

Esta anotación se puede usar para inyectar valores en campos en beans administrados por Spring, y se puede aplicar a nivel de parámetro de campo o constructor / método.

2. Configuración de la aplicación

Para describir los diferentes tipos de uso de esta anotación, necesitamos configurar una clase de configuración de aplicación Spring simple.

Naturalmente, necesitaremos un archivo de propiedades para definir los valores que queremos inyectar con la anotación @Value . Entonces, primero necesitaremos definir un @PropertySource en nuestra clase de configuración, con el nombre del archivo de propiedades.

Definamos el archivo de propiedades:

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

3. Ejemplos de uso

Como ejemplo básico y en su mayoría inútil, solo podemos inyectar "valor de cadena" desde la anotación al campo:

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

El uso de la anotación @PropertySource nos permite trabajar con valores de archivos de propiedades con la anotación @Value .

En el siguiente ejemplo, obtenemos el valor obtenido del archivo asignado al campo:

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

También podemos establecer el valor de las propiedades del sistema con la misma sintaxis.

Supongamos que hemos definido una propiedad del sistema llamada systemValue :

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

Se pueden proporcionar valores predeterminados para propiedades que pueden no estar definidas. Aquí, se inyectará el valor por defecto :

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

Si la misma propiedad está definida como propiedad del sistema y en el archivo de propiedades, entonces se aplicaría la propiedad del sistema.

Supongamos que tenemos una prioridad de propiedad definida como una propiedad del sistema con el valor Propiedad del sistema y definida como algo más en el archivo de propiedades. El valor sería propiedad del sistema :

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

A veces, necesitamos inyectar un montón de valores. Sería conveniente definirlos como valores separados por comas para la propiedad única en el archivo de propiedades o como una propiedad del sistema e inyectarlos en una matriz.

En la primera sección, definimos valores separados por comas en el listOfValues del archivo de propiedades , por lo que los valores de la matriz serían ["A", "B", "C"]:

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

4. Ejemplos avanzados con SpEL

También podemos usar expresiones SpEL para obtener el valor.

Si tenemos una propiedad del sistema llamada prioridad, entonces su valor se aplicará al campo:

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

Si no hemos definido la propiedad del sistema, se asignará el valor nulo .

Para evitar esto, podemos proporcionar un valor predeterminado en la expresión SpEL. Obtenemos un valor predeterminado para el campo si la propiedad del sistema no está definida:

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

Además, podemos usar un valor de campo de otros beans. Supongamos que tenemos un bean llamado someBean con un campo someValue igual a 10 . Luego, se asignarán 10 al campo:

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

Podemos manipular las propiedades para obtener una lista de valores, aquí, una lista de valores de cadena A, B y C:

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

5. Uso de @Value con mapas

También podemos usar la anotación @Value para inyectar una propiedad Map .

Primero, necesitaremos definir la propiedad en el formulario {clave: 'valor'} en nuestro archivo de propiedades:

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

Tenga en cuenta que los valores del mapa deben estar entre comillas simples.

Ahora podemos inyectar este valor del archivo de propiedades como un mapa :

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

Si necesitamos obtener el valor de una clave específica en el Mapa , todo lo que tenemos que hacer es agregar el nombre de la clave en la expresión :

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

Si no estamos seguros de si el mapa contiene una determinada clave, debemos elegir una expresión más segura que no genere una excepción, pero establezca el valor en nulo cuando no se encuentre la clave:

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

También podemos establecer valores predeterminados para las propiedades o claves que podrían no existir :

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

Las entradas del mapa también se pueden filtrar antes de la inyección.

Supongamos que necesitamos obtener solo aquellas entradas cuyos valores son mayores que uno:

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

También podemos usar la anotación @Value para inyectar todas las propiedades del sistema actual :

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

6. Uso de @Value con inyección de constructor

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

En este artículo, examinamos las diversas posibilidades de usar la anotación @Value con propiedades simples definidas en el archivo, con propiedades del sistema y con propiedades calculadas con expresiones SpEL.

Como siempre, la aplicación de ejemplo está disponible en el proyecto GitHub.