Spring AOP代理源码解析:JDK动态代理、CGLIB动态代理分析

落日余晖 2024-08-14 ⋅ 20 阅读

在Spring框架中,AOP(面向切面编程)是一种编程范式,它允许开发者在应用程序的主要业务逻辑之外定义横切关注点,如日志、事务管理等。Spring AOP通过代理技术实现,其中包括JDK动态代理和CGLIB动态代理两种方式。在本文中,我们将深入分析Spring AOP代理的实现原理,并通过源代码解析来探讨它们的实现细节。

JDK动态代理

JDK动态代理是通过反射机制实现的动态代理技术。在Spring AOP中,JDK动态代理主要用于代理实现了接口的类。当创建目标对象的代理时,Spring会使用java.lang.reflect.Proxy类来动态生成代理类并实例化。代理对象的方法调用会被重定向到InvocationHandler接口的实现类中,从而实现横切逻辑的织入。

下面是一个简单的示例代码,演示了如何使用JDK动态代理创建代理对象:

public interface UserService {
    void addUser();
}

public class UserServiceImpl implements UserService {
    @Override
    public void addUser() {
        System.out.println("Adding user...");
    }
}

public class LogInterceptor implements InvocationHandler {
    private Object target;

    public LogInterceptor(Object target) {
        this.target = target;
    }

    @Override
    public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {
        System.out.println("Before method " + method.getName());
        Object result = method.invoke(target, args);
        System.out.println("After method " + method.getName());
        return result;
    }
}

public class Main {
    public static void main(String[] args) {
        UserService target = new UserServiceImpl();
        LogInterceptor interceptor = new LogInterceptor(target);
        
        UserService proxy = (UserService) Proxy.newProxyInstance(
            target.getClass().getClassLoader(),
            target.getClass().getInterfaces(),
            interceptor
        );
        
        proxy.addUser();
    }
}

CGLIB动态代理

CGLIB(Code Generation Library)是一个基于ASM的字节码生成库,它可以在运行时创建目标类的子类实现代理。CGLIB动态代理主要用于代理没有实现接口的类。在Spring AOP中,当目标类没有实现接口时,Spring会使用CGLIB动态代理生成代理对象的子类,并在运行时通过字节码增强技术来实现横切逻辑的织入。

下面是一个简单的示例代码,演示了如何使用CGLIB动态代理创建代理对象:

public class UserService {
    public void addUser() {
        System.out.println("Adding user...");
    }
}

public class LogInterceptor implements MethodInterceptor {
    @Override
    public Object intercept(Object obj, Method method, Object[] args, MethodProxy proxy) throws Throwable {
        System.out.println("Before method " + method.getName());
        Object result = proxy.invokeSuper(obj, args);
        System.out.println("After method " + method.getName());
        return result;
    }
}

public class Main {
    public static void main(String[] args) {
        Enhancer enhancer = new Enhancer();
        enhancer.setSuperclass(UserService.class);
        enhancer.setCallback(new LogInterceptor());
        
        UserService proxy = (UserService) enhancer.create();
        proxy.addUser();
    }
}

通过以上示例,我们可以清楚地了解到Spring AOP中JDK动态代理和CGLIB动态代理的实现原理,以及它们在代理对象创建和横切逻辑织入方面的差异。在实际开发中,根据目标类是否实现接口来选择合适的代理方式是非常关键的,希


全部评论: 0

    我有话说: