Prioridad de Intercepción en Spring Boot AOP

En el desarrollo con Spring Boot, el uso de AOP (Programación Oreintada a Aspectos) es esencial para gestionar preocupaciones transversales como logging, seguridad y transacciones. Un aspecto crítico es el orden en que se ejecutan diferentes consejos (advice) cuando interceptan el mismo método. Este artículo analiza en detalle las reglas de prioridad en diferentes escenarios de configuración.

Prioridad de Consejos en un Mismo Aspecto

Cuando múltiples consejos del mismo tipo, como @Before, están configurados en un único aspecto y apuntan al mismo método objetivo, el orden de ejecución está determinado por el orden alfabético de sus nombres de método. El uso de la anotación @Order en este contexto no tiene efecto sobre la prioridad.

Consideremos un componente de servicio simple:

@Component
public class ServicioDemo {
    @OperacionPersonalizada
    public String ejecutar() {
        try {
            System.out.println("Inicio del servicio");
            String resultado = System.currentTimeMillis() + "|" + UUID.randomUUID().toString();
            System.out.println(resultado);
            return resultado;
        } finally {
            System.out.println("Fin del servicio");
        }
    }
}

Un aspecto con múltiples tipos de consejo:

@Component
@Aspect
public class AspectoPrincipal {

    @Pointcut("execution(public * com.ejemplo.demo.*.*())")
    public void puntoDeCorte() {
    }

    @Before(value = "puntoDeCorte()")
    public void antes(JoinPoint punto) {
        System.out.println("Antes de la ejecución");
    }

    @After(value = "puntoDeCorte()")
    public void despues(JoinPoint punto) {
        System.out.println("Después de la ejecución");
    }

    @AfterReturning(value = "puntoDeCorte()", returning = "resultado")
    public void despuesDeRetorno(JoinPoint punto, String resultado) {
        System.out.println("Retorno obtenido: " + resultado);
    }

    @Around("puntoDeCorte()")
    public Object alrededor(ProceedingJoinPoint punto) throws Throwable {
        try {
            System.out.println("Iniciando rodeo");
            return punto.proceed();
        } finally {
            System.out.println("Finalizando rodeo");
        }
    }
}

Al ejecutar, la salida mostrará el siguiente orden predecible:

Iniciando rodeo
Antes de la ejecución
Inicio del servicio
1552219604035|e9a31f44-6a31-4485-806a-834361842ce1
Fin del servicio
Finalizando rodeo
Después de la ejecución
Retorno obtenido: 1552219604035|e9a31f44-6a31-4485-806a-834361842ce1

Consejos del Mismo Tipo en Distintos Aspectos

Cuando dos aspectos diferentes definen consejos del mismo tipo (por ejemplo, ambos con @Before) para el mismo método, la prioridad por defecto está determinada por el nombre de la clase del aspecto. Para controlar explícitamente el orden, se utiliza la anotación @Order a nivel de clase, donde un valor numérico menor indica mayor prioridad.

Un segundo aspecto para demostrar la prioridad:

@Aspect
@Component
@Order(10) // Prioridad más baja
public class AspectoSecundario {
    @Before("@annotation(OperacionPersonalizada)")
    public void verificarPermisos() {
        System.out.println("Verificación de permisos");
    }
}

Aplicar @Order al aspecto principal con un valor menor garantiza su ejecución primero:

@Component
@Aspect
@Order(1) // Prioridad más alta
public class AspectoPrincipal {
    // ... mismos consejos que antes
}

La salida confirma que los consejos del aspecto con mayor prioridad envuelven completamente a los del aspecto con menor prioridad.

Orden de Ejecución General

La secuencia completa de ejecución para diferentes tipos de consejos, considerando la prioridad entre aspectos, se puede resumir de la siguiente manera:

Alrededor (antes) -> Antes -> Ejecución del método -> Alrededor (después) -> Después -> DespuésRetorno

Para la gestión de prioridades entre aspectos, la recomendación clara es utilizar la anotación @Order en la definición de la clase del aspecto. Dentro de un mismo aspecto, el nombre del método del consejo es el único factor determinante para los consejos del mismo tipo.

Etiquetas: Spring Boot AOP Consejos Intercepción Orden de Ejecución

Publicado el 7-1 21:54