**Мій герой**
Оксана прогладила спідницю перед дзеркалом, наклала рожеву помаду на губи, потім поправила пружинячий локон. Відійшла на крок назад і прискіпливо оглянула себе. «Гарна!» — задоволено посміхнулася своєму відображенню.
У дверях приймальні з’явився чоловік, притулившись плечем до косяка.
— Ого! Куди це ти так припарадилась?
— На роботу. Ревнуєш, чи що? — Оксана округлила свої й так великі, гарно підведені очі.
— Авжеж, ревную. Може, відвезу тебе на авто? У маршрутці всі помнуться, — запропонував Богдан.
— Сиди вдома. Куди тобі з гіпсом? — Оксана застебнула блискуче стегнате пальто, поправила шарф на шиї, підібравши його аж до підборіддя.
— Пішла я. — Але біля дверей зупинилася.
— Так, зовсім забула. Затримаюся. Марія виходить заміж. Буде щось на кшталт дівич-вечора. Посидимо в кафе. Не хвилюйся.
— Почекай, може, все ж таки заберу тебе? — Богдан відірвав плече від дверей.
— Не треба. — Оксана витягла губи, послала повітряний поцілунок і вийшла.
Богдан підійшов до вікна, чекаючи, поки внизу з’явиться Оксана.
— Скільки можна казати, щоб права здала. Зараз би на машині �La **Programación Orientada a Aspectos (POA)** es un paradigma de programación que busca aumentar la **modularidad** del código al permitir la **separación de preocupaciones transversales** (**cross-cutting concerns**). Estas son funcionalidades que afectan a múltiples partes de un sistema y que, en la programación tradicional, suelen estar dispersas o duplicadas en varias partes del código (por ejemplo, logging, seguridad, transacciones, etc.).
La POA introduce el concepto de **aspecto**, que encapsula estas preocupaciones transversales y permite definir **puntos de corte (pointcuts)** donde estos aspectos deben aplicarse, así como el **consejo (advice)**, que es el código que se ejecutará en esos puntos.
—
## **1. ¿Qué es un Aspecto?**
Un **aspecto** es una unidad modular que encapsula un comportamiento transversal que afecta a múltiples clases o módulos. Los aspectos permiten:
– **Separar** la lógica transversal (como logging, seguridad, transacciones).
– **Centralizar** esta lógica en lugar de repetirla en varias partes del código.
– **Mejorar la mantenibilidad**, ya que los cambios en estos comportamientos se hacen en un solo lugar.
—
## **2. Componentes de la POA**
Los elementos clave de la POA son:
| Concepto | Descripción | Ejemplo |
|———-|————|———|
| **Join Point (Punto de Unión)** | Puntos específicos en la ejecución del programa donde un aspecto se puede aplicar (ej: llamada a método, acceso a campo). | Llamada a `service.crearUsuario()`. |
| **Pointcut (Punto de Corte)** | Expresión que define en qué join points se aplicará el aspecto. | `@Pointcut(“execution(* com.ejemplo.service.*.*(..))”)` |
| **Advice (Consejo)** | Código que se ejecuta en los join points seleccionados por el pointcut. | `@Before`, `@After`, `@Around`. |
| **Aspect (Aspecto)** | Clase que contiene pointcuts y advices. | Una clase anotada con `@Aspect`. |
| **Weaving (Tejido)** | Proceso de integrar los aspectos en el código base (puede ser en tiempo de compilación, carga o ejecución). | Compilación con **AspectJ**. |
—
## **3. Ejemplo Práctico (Spring AOP + AspectJ)**
Supongamos que queremos **loggear** cada vez que se llama a un método de un servicio:
“`java
import org.aspectj.lang.annotation.*;
import org.springframework.stereotype.Component;
@Aspect // Define que esta clase es un Aspecto
@Component // Para que Spring lo reconozca
public class LoggingAspect {
// Define un Pointcut que afecte a todos los métodos de los servicios
@Pointcut(“execution(* com.example.service.*.*(..))”)
public void serviceMethods() {}
// Advice que se ejecuta ANTES del método marcado por el Pointcut
@Before(“serviceMethods()”)
public void logBeforeMethodCall() {
System.out.println(“[LOG] Método de servicio llamado”);
}
// Advice que se ejecuta DESPUÉS del método (incluso si lanza excepción)
@After(“serviceMethods()”)
public void logAfterMethodCall() {
System.out.println(“[LOG] Método de servicio finalizado”);
}
}
“`
—
## **4. Tipos de Advice**
| Tipo | Descripción | Ejemplo |
|——|————-|———|
| **@Before** | Se ejecuta **antes** del método. | Loggear inicio de transacción. |
| **@After** | Se ejecuta **después** del método (éxito o fallo). | Liberar recursos. |
| **@AfterReturning** | Se ejecuta solo si el método termina **correctamente**. | Loggear éxito. |
| **@AfterThrowing** | Se ejecuta solo si el método **lanza excepción**. | Loggear error. |
| **@Around** | **Envuelve** la ejecución del método (permite modificar parámetros o resultado). | Medir tiempo de ejecución. |
### **Ejemplo con @Around**
“`java
@Around(“serviceMethods()”)
public Object measureExecutionTime(ProceedingJoinPoint joinPoint) throws Throwable {
long startTime = System.currentTimeMillis();
// Ejecuta el método original
Object result = joinPoint.proceed();
long endTime = System.currentTimeMillis();
System.out.println(“[PERF] ” + joinPoint.getSignature() + ” ejecutado en ” + (endTime – startTime) + “ms”);
return result;
}
“`
—
## **5. Beneficios de la POA**
✅ **Reducción de código repetitivo** (DRY – Don’t Repeat Yourself).
✅ **Mayor modularidad** al separar preocupaciones transversales.
✅ **Facilidad de mantenimiento**: cambios en logging, seguridad, etc., se hacen en un solo lugar.
✅ **No invasivo**: No es necesario modificar las clases originales.
—
## **6. Frameworks para POA**
– **AspectJ**: La implementación más completa (soporta weaving en tiempo de compilación y carga).
– **Spring AOP**: Implementación más ligera basada en proxies (solo método-level join points).
– **CDI Interceptors (Java EE)**: Similar a AOP, pero con anotaciones `@Interceptor`.
—
## **Conclusión**
La **POA** ayuda a manejar preocupaciones transversales de manera limpia y modular. Su uso es especialmente útil en **logging, seguridad, transacciones y monitorización de rendimiento**.
> **📌 Nota:** En **Spring Boot**, puedes habilitar AOP añadiendo `@EnableAspectJAutoProxy` en una clase de configuración.