Translate

miércoles, 5 de marzo de 2025

Cómo Spring Implementa AOP


Spring AOP se basa en el Patrón Proxy y la generación dinámica de clases para aplicar aspectos sin modificar el código fuente original.

Spring AOP crea proxies para interceptar llamadas a métodos y aplicar lógica adicional. Dependiendo de la estructura de la clase objetivo, Spring elige entre dos enfoques:

JDK Dynamic Proxies: Si la clase implementa una interfaz, Spring usa java.lang.reflect.Proxy para generar un proxy en tiempo de ejecución.

CGLIB (Code Generation Library): Si la clase no implementa interfaces, se genera una subclase dinámica con CGLIB.


Veamos un ejemplo de un proxy con JDK:


import java.lang.reflect.*;


interface Servicio {

    void ejecutar();

}


class ServicioImpl implements Servicio {

    public void ejecutar() {

        System.out.println("Ejecutando servicio...");

    }

}


class ProxyHandler implements InvocationHandler {

    private final Object target;

    public ProxyHandler(Object target) {

        this.target = target;

    }

    public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {

        System.out.println("[AOP] Antes de ejecutar");

        Object result = method.invoke(target, args);

        System.out.println("[AOP] Después de ejecutar");

        return result;

    }

}


public class Main {

    public static void main(String[] args) {

        Servicio servicio = (Servicio) Proxy.newProxyInstance(

            Servicio.class.getClassLoader(),

            new Class[]{Servicio.class},

            new ProxyHandler(new ServicioImpl()));

        servicio.ejecutar();

    }

}


Si la clase no implementa interfaces, Spring usa CGLIB para generar una subclase dinámica.


import net.sf.cglib.proxy.*;


class Servicio {

    public void ejecutar() {

        System.out.println("Ejecutando servicio...");

    }

}


class Interceptor implements MethodInterceptor {

    public Object intercept(Object obj, Method method, Object[] args, MethodProxy proxy) throws Throwable {

        System.out.println("[AOP] Antes de ejecutar");

        Object result = proxy.invokeSuper(obj, args);

        System.out.println("[AOP] Después de ejecutar");

        return result;

    }

}


public class Main {

    public static void main(String[] args) {

        Enhancer enhancer = new Enhancer();

        enhancer.setSuperclass(Servicio.class);

        enhancer.setCallback(new Interceptor());

        Servicio proxy = (Servicio) enhancer.create();

        proxy.ejecutar();

    }

}


Spring AOP aplica aspectos mediante proxies dinámicos. Si la clase tiene una interfaz, usa JDK Dynamic Proxies; si no, usa CGLIB para generar una subclase dinámica. Esto permite agregar lógica sin modificar el código fuente ni el bytecode.