Translate

Mostrando las entradas con la etiqueta AOP. Mostrar todas las entradas
Mostrando las entradas con la etiqueta AOP. Mostrar todas las entradas

sábado, 1 de marzo de 2025

Programación Orientada a Aspectos (AOP) en Spring


La Programación Orientada a Aspectos (AOP, Aspect-Oriented Programming) es un paradigma que permite separar las preocupaciones transversales del código principal, como logging, seguridad, manejo de transacciones y monitoreo. Spring proporciona Spring AOP y compatibilidad con AspectJ para implementar esta funcionalidad de manera eficiente.

En una aplicación, hay funcionalidades que se repiten en diferentes partes del código (logging, manejo de excepciones, validaciones). Sin AOP, estas funciones deben implementarse de forma manual en cada clase, lo que genera código repetitivo y difícil de mantener.

AOP permite interceptar la ejecución de métodos y agregar lógica adicional sin modificar la implementación original.

Veamos un ejemplo. Para implementar un aspecto en Spring, necesitamos habilitar AOP y definir un aspecto con consejos (`advice`).

Primero agregamos la dependencia, en este ejemplo uso maven: 


<dependency>

    <groupId>org.springframework.boot</groupId>

    <artifactId>spring-boot-starter-aop</artifactId>

</dependency>


@Configuration

@EnableAspectJAutoProxy

@ComponentScan("com.example")

public class AppConfig {

}


Ahora definimos el aspecto de Logging


import org.aspectj.lang.annotation.*;

import org.springframework.stereotype.Component;


@Aspect

@Component

public class LoggingAspect {

    

    @Before("execution(* com.example.service.*.*(..))")

    public void logBeforeMethod() {

        System.out.println("[LOG] - Método invocado...");

    }

}


@Aspect: Indica que la clase es un aspecto.

@Before("execution(* com.example.service.*.*(..))"): Aplica el aspecto antes de ejecutar cualquier método dentro del paquete `com.example.service`.

execution(* com.example.service.*.*(..)): Todos los métodos de cualquier clase en com.example.service.

Podemos usar @Around para envolver la ejecución de un método y medir su tiempo de respuesta.


import org.aspectj.lang.ProceedingJoinPoint;

import org.aspectj.lang.annotation.*;

import org.springframework.stereotype.Component;


@Aspect

@Component

public class PerformanceAspect {

    

    @Around("execution(* com.example.service.*.*(..))")

    public Object measureExecutionTime(ProceedingJoinPoint joinPoint) throws Throwable {

        long start = System.currentTimeMillis();

        Object result = joinPoint.proceed(); // Llama al método original

        long end = System.currentTimeMillis();

        System.out.println("Tiempo de ejecución: " + (end - start) + "ms");

        return result;

    }

}

@Around: Permite modificar la ejecución del método original.

joinPoint.proceed(): Ejecuta el método interceptado.

System.currentTimeMillis(): Mide el tiempo antes y después de la ejecución.


Ahora veamos un ejemplo con AspectJ: Spring AOP solo funciona con beans de Spring, pero si queremos interceptar cualquier clase, podemos usar AspectJ full.

Agregamos a nuestro pom: 


<dependency>

    <groupId>org.aspectj</groupId>

    <artifactId>aspectjweaver</artifactId>

    <version>1.9.7</version>

</dependency>


Habilitamos AspectJ en Spring Boot


@EnableAspectJAutoProxy(proxyTargetClass = true)


Definimos un aspecto con AspectJ


@Aspect

public class SecurityAspect {

    

    @Before("execution(* *(..))") // Aplica a cualquier método

    public void checkSecurity() {

        System.out.println("[SECURITY] - Verificando permisos...");

    }

}

Spring AOP permite separar lógica transversal, reduciendo la repetición de código y mejorando la mantenibilidad. Con @Aspect y @Pointcut, podemos interceptar métodos y agregar funcionalidades como logging, seguridad y performance. Para casos avanzados, AspectJ permite interceptar cualquier clase en la aplicación.