SpEL, lenguaje de expresiones de Spring Framework

Spring framework, es en el ecosistema Java sin querer ser absoluto el marco de desarrollo más ampliamente adoptado, sobre todo impulsado por proyectos con Spring Boot & Spring Cloud. La popularidad de Spring se debe, además, a las facilidades y bibliotecas de utilidades que posee. Una de las cuestiones más usadas a diario de Spring es su lenguaje de expresiones, un ejemplo de ello es cada vez que usamos la anotación @Value, sin embargo su potencial es alto y poco explotado.

En esta entrada hablaremos de SpEL.

¿Qué es SpEL ?

Spring Expression Language (SpEL), es un poderoso lenguaje de expresión que admite consultas y manipulación de objetos en tiempo de ejecución. La sintaxis del lenguaje es similar a la del Lenguaje Unificado de Expresiones (definido en la JSR 245), pero ofrece características adicionales, especialmente la invocación de métodos y la funcionalidad básica de plantillas de cadenas.

Spring Expression Language fue creado para proporcionar a la comunidad de Spring un lenguaje de expresión único y compatible que se pueda utilizar en todos los productos y bibliotecas de Spring.

Características de SpEL

Cuando usamos SpEL contamos con las siguientes características que soporta.

  • Expresiones literales.
  • Operadores booleanos.
  • Expresiones regulares.
  • Expresiones de clase.
  • Acceso a propiedades / atributos.
  • Invocación de métodos.
  • Operadores relacionales.
  • Llamando a constructores.
  • Referencias a Beans.
  • Soporte para listas y mapas.

ExpressionParser

SpEL está centrado en la interfaz de Java ExpressionParser, la cual posee el método principal parseExpression(String), y una variación sobre cargada del mismo. Este método recibe una cadena y devuelve una Expression que puede ser posteriormente evaluada. Salvando las distancias el funcionamiento es similar a eval de PHP.

SpEL en Spring está en el paquete:

 org.springframework.expression

Ejemplo usando ExpressionParser

Veamos algunos ejemplos de uso de ExpressionParser.

Ejemplo 1: Evaluar una expresión constante.

ExpressionParser parser = new SpelExpressionParser();
Expression exp = parser.parseExpression("'Hola mundo'");
String message = (String) exp.getValue();

Ejemplo 2: Evaluar una expresión que ejecute una operación sobre una cadena.

ExpressionParser parser = new SpelExpressionParser();<br>Expression exp = parser.parseExpression("'Hola mundo '.substring(0,5)");
String message = (String) exp.getValue();

En el ejemplo anterior, vamos de String constante ‘Hola mundo’ extraer los primeros 5 caracteres.

Ejemplo 3: Sumando dos números.

ExpressionParser parser = new SpelExpressionParser();
Expression exp = parser.parseExpression("new Integer(5) + 5");
Integer res = (Integer) exp.getValue(exp);
      

SpEL completamente integrado con Spring

El verdadero provecho de SpEL se saca en la integración directa que brinda en Spring Framework, como comentábamos al inicio, el caso más común es cuando lo usamos para inyectar propiedades a los atributos desde la configuración con @Value.

Ejemplo 1: Mapeando una constante a un atributo.

@Value("cadena")
private String stringValue;

Ejemplo 2: Mapeando a un atributo de la configuración.

@Value("${valor.desde.archivo.conf}")
private String valueFromFile;

Ejemplo 3: Mapeando a un atributo de la configuración con valor por defecto.

@Value("${valor.desde.archivo.conf:true}")
private Boolean valueFromFile;

Ejemplo 4: Leyendo una lista de valores separados por coma desde configuración.

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

Ejemplo 5: Cargando un Map desde configuración

valuesMap={key1: '1', key2: '2', key3: '3'}
@Value("#{${valuesMap}}")
private Map<String, Integer> valuesMap;

El valuesMap del ejemplo anterior es la línea que va en el archivo de configuración.

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

En la variante del ejemplo anterior podemos aplicar SpEL para filtrar y solo quedarnos con los elementos del mapa que cumplan que el valor (key, value) sea superior a 1.

Estas operaciones además de poder ser aplicadas sobre atributos @Value permite sean aplicadas sobre constructores y setters.

Plantillas de expresiones

Con SpEL también podemos usar template expressions para mappear parámetros de funciones, similar a cómo vimos con @Value con el operador #{}. SpEL cuenta además con el operador T que puede ser usado para especificar una instancia de java.lang.Class; la referencia a la clase que se va evaluar por T debe poseer el package path completo.

Veamos un ejemplo:

@Cacheable(value = "cache1", key = "T(java.lang.String).format('%s_%s', #nombre, #apellidos)")
    public Usuario (String nombre, String apellidos) {
        return new Usuario ("Jhon", "Doe")
    }

En el ejemplo anterior supongamos estamos usando el sistema de Cache de Spring con la anotación @Cacheable, la misma entre múltiples parámetros soporta que establezcamos la key de la cache, en este ejemplo usamos SpEL para crear la clave a partir los parámetros del método y con el operador T, para la clase String (java.lang.String) invocamos el método format, obtenemos el valor de nombre y apellidos con el operador #.

SpEL es muy amplio, en este artículo solo vimos elementos generales y algunos ejemplos.

Puedes acceder a toda la documentación oficial.

2 thoughts on “SpEL, lenguaje de expresiones de Spring Framework

Comments are closed.