Java实现动态代理案例

wen java案例 1

本文目录导读:

Java实现动态代理案例

  1. JDK动态代理(基于接口)
  2. CGLIB动态代理(基于类继承)
  3. 通用动态代理工具类
  4. 完整测试示例
  5. 实际应用场景示例(AOP)
  6. 注意事项和最佳实践

我来为你展示Java动态代理的完整案例,包括JDK动态代理和CGLIB动态代理两种实现方式。

JDK动态代理(基于接口)

基础接口和实现类

// 业务接口
public interface UserService {
    void addUser(String name);
    String getUser(int id);
    void deleteUser(int id);
}
// 业务实现类
public class UserServiceImpl implements UserService {
    @Override
    public void addUser(String name) {
        System.out.println("添加用户: " + name);
    }
    @Override
    public String getUser(int id) {
        System.out.println("查询用户: " + id);
        return "用户" + id;
    }
    @Override
    public void deleteUser(int id) {
        System.out.println("删除用户: " + id);
    }
}

JDK动态代理实现

import java.lang.reflect.InvocationHandler;
import java.lang.reflect.Method;
import java.lang.reflect.Proxy;
public class JdkProxyFactory {
    // 创建代理对象
    public static Object createProxy(Object target) {
        return Proxy.newProxyInstance(
            target.getClass().getClassLoader(),
            target.getClass().getInterfaces(),
            new LogInvocationHandler(target)
        );
    }
    // 日志代理处理器
    static class LogInvocationHandler implements InvocationHandler {
        private final Object target;
        public LogInvocationHandler(Object target) {
            this.target = target;
        }
        @Override
        public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {
            // 前置处理
            System.out.println("[JDK代理] 调用方法: " + method.getName() + 
                             ", 参数: " + java.util.Arrays.toString(args));
            long startTime = System.currentTimeMillis();
            // 调用目标方法
            Object result = method.invoke(target, args);
            // 后置处理
            long endTime = System.currentTimeMillis();
            System.out.println("[JDK代理] 方法执行完毕, 耗时: " + (endTime - startTime) + "ms");
            return result;
        }
    }
}

CGLIB动态代理(基于类继承)

CGLIB依赖(Maven)

<dependency>
    <groupId>cglib</groupId>
    <artifactId>cglib</artifactId>
    <version>3.3.0</version>
</dependency>

CGLIB动态代理实现

import net.sf.cglib.proxy.Enhancer;
import net.sf.cglib.proxy.MethodInterceptor;
import net.sf.cglib.proxy.MethodProxy;
import java.lang.reflect.Method;
public class CglibProxyFactory {
    // 创建代理对象
    public static Object createProxy(Class<?> targetClass) {
        Enhancer enhancer = new Enhancer();
        // 设置父类
        enhancer.setSuperclass(targetClass);
        // 设置回调
        enhancer.setCallback(new LogMethodInterceptor());
        // 创建代理对象
        return enhancer.create();
    }
    // 方法拦截器
    static class LogMethodInterceptor implements MethodInterceptor {
        @Override
        public Object intercept(Object obj, Method method, Object[] args, 
                               MethodProxy proxy) throws Throwable {
            // 前置处理
            System.out.println("[CGLIB代理] 调用方法: " + method.getName() + 
                             ", 参数: " + java.util.Arrays.toString(args));
            long startTime = System.currentTimeMillis();
            // 调用父类方法
            Object result = proxy.invokeSuper(obj, args);
            // 后置处理
            long endTime = System.currentTimeMillis();
            System.out.println("[CGLIB代理] 方法执行完毕, 耗时: " + (endTime - startTime) + "ms");
            return result;
        }
    }
}

通用动态代理工具类

import java.lang.reflect.InvocationHandler;
import java.lang.reflect.Method;
import java.lang.reflect.Proxy;
public class ProxyUtil {
    // JDK动态代理(通用)
    public static <T> T createJdkProxy(T target, ProxyHandler handler) {
        return (T) Proxy.newProxyInstance(
            target.getClass().getClassLoader(),
            target.getClass().getInterfaces(),
            new InvocationHandler() {
                @Override
                public Object invoke(Object proxy, Method method, Object[] args) 
                        throws Throwable {
                    handler.before(method, args);
                    Object result = method.invoke(target, args);
                    handler.after(method, result);
                    return result;
                }
            }
        );
    }
    // 代理处理器接口
    public interface ProxyHandler {
        void before(Method method, Object[] args);
        void after(Method method, Object result);
    }
    // 使用示例
    public static void main(String[] args) {
        UserService userService = new UserServiceImpl();
        UserService proxy = createJdkProxy(userService, new ProxyHandler() {
            @Override
            public void before(Method method, Object[] args) {
                System.out.println("【通用代理】准备调用: " + method.getName());
            }
            @Override
            public void after(Method method, Object result) {
                System.out.println("【通用代理】调用结束: " + method.getName() + 
                                 ", 结果: " + result);
            }
        });
        proxy.addUser("张三");
        proxy.getUser(1);
    }
}

完整测试示例

public class DynamicProxyTest {
    public static void main(String[] args) {
        System.out.println("=== JDK动态代理测试 ===");
        testJdkProxy();
        System.out.println("\n=== CGLIB动态代理测试 ===");
        testCglibProxy();
        System.out.println("\n=== 性能对比测试 ===");
        testPerformance();
    }
    // JDK代理测试
    private static void testJdkProxy() {
        UserService userService = new UserServiceImpl();
        UserService proxy = (UserService) JdkProxyFactory.createProxy(userService);
        // 调用代理方法
        proxy.addUser("张三");
        String user = proxy.getUser(1001);
        proxy.deleteUser(1001);
        System.out.println("代理对象类: " + proxy.getClass().getName());
        System.out.println("是否代理对象: " + Proxy.isProxyClass(proxy.getClass()));
    }
    // CGLIB代理测试
    private static void testCglibProxy() {
        UserServiceImpl proxy = (UserServiceImpl) CglibProxyFactory
            .createProxy(UserServiceImpl.class);
        // 调用代理方法
        proxy.addUser("李四");
        String user = proxy.getUser(1002);
        proxy.deleteUser(1002);
        System.out.println("代理对象类: " + proxy.getClass().getName());
    }
    // 性能对比测试
    private static void testPerformance() {
        final int LOOP_COUNT = 10000;
        // 测试原始对象
        UserService original = new UserServiceImpl();
        long start = System.currentTimeMillis();
        for (int i = 0; i < LOOP_COUNT; i++) {
            original.getUser(i);
        }
        long originalTime = System.currentTimeMillis() - start;
        // 测试JDK代理
        UserService jdkProxy = (UserService) JdkProxyFactory.createProxy(original);
        start = System.currentTimeMillis();
        for (int i = 0; i < LOOP_COUNT; i++) {
            jdkProxy.getUser(i);
        }
        long jdkTime = System.currentTimeMillis() - start;
        // 测试CGLIB代理
        UserServiceImpl cglibProxy = (UserServiceImpl) CglibProxyFactory
            .createProxy(UserServiceImpl.class);
        start = System.currentTimeMillis();
        for (int i = 0; i < LOOP_COUNT; i++) {
            cglibProxy.getUser(i);
        }
        long cglibTime = System.currentTimeMillis() - start;
        System.out.println("原始对象耗时: " + originalTime + "ms");
        System.out.println("JDK代理耗时: " + jdkTime + "ms");
        System.out.println("CGLIB代理耗时: " + cglibTime + "ms");
    }
}

实际应用场景示例(AOP)

import java.lang.annotation.*;
import java.lang.reflect.InvocationHandler;
import java.lang.reflect.Method;
import java.lang.reflect.Proxy;
// 自定义注解
@Target(ElementType.METHOD)
@Retention(RetentionPolicy.RUNTIME)
@interface Log {
    String value() default "";
}
@Target(ElementType.METHOD)
@Retention(RetentionPolicy.RUNTIME)
@interface Transaction {
}
// 业务类
class OrderService {
    @Log("创建订单")
    @Transaction
    public void createOrder(String orderId) {
        System.out.println("创建订单: " + orderId);
    }
    @Log("查询订单")
    public String getOrder(String orderId) {
        System.out.println("查询订单: " + orderId);
        return "订单信息-" + orderId;
    }
    @Transaction
    public void cancelOrder(String orderId) {
        System.out.println("取消订单: " + orderId);
    }
}
// 自定义动态代理(模拟AOP)
public class AopProxy {
    public static <T> T createAopProxy(T target, Class<?> targetClass) {
        return (T) Proxy.newProxyInstance(
            targetClass.getClassLoader(),
            targetClass.getInterfaces(),
            new AopInvocationHandler(target, targetClass)
        );
    }
    static class AopInvocationHandler implements InvocationHandler {
        private final Object target;
        private final Class<?> targetClass;
        public AopInvocationHandler(Object target, Class<?> targetClass) {
            this.target = target;
            this.targetClass = targetClass;
        }
        @Override
        public Object invoke(Object proxy, Method method, Object[] args) 
                throws Throwable {
            // 获取原始方法(含注解)
            Method originalMethod = targetClass.getMethod(method.getName(), 
                                                       method.getParameterTypes());
            Object result = null;
            // 检查是否包含@Transaction注解
            if (originalMethod.isAnnotationPresent(Transaction.class)) {
                System.out.println("[事务] 开启事务");
                try {
                    result = method.invoke(target, args);
                    System.out.println("[事务] 提交事务");
                } catch (Exception e) {
                    System.out.println("[事务] 回滚事务");
                    throw e;
                }
            } else {
                result = method.invoke(target, args);
            }
            // 检查是否包含@Log注解
            if (originalMethod.isAnnotationPresent(Log.class)) {
                Log log = originalMethod.getAnnotation(Log.class);
                System.out.println("[日志] " + log.value() + " - " + 
                                 java.util.Arrays.toString(args));
            }
            return result;
        }
    }
    public static void main(String[] args) {
        // 创建代理
        OrderService service = new OrderService();
        OrderService proxy = createAopProxy(service, OrderService.class);
        // 测试
        proxy.createOrder("ORD001");
        System.out.println("---");
        proxy.getOrder("ORD002");
        System.out.println("---");
        proxy.cancelOrder("ORD003");
    }
}

注意事项和最佳实践

选择建议

public class ProxySelectionGuide {
    public static void main(String[] args) {
        // 强烈推荐:Spring中优先使用JDK动态代理
        /*
         * 选择策略:
         * 1. 有接口时优先使用JDK动态代理
         *    - 标准JDK功能,无需额外依赖
         *    - 性能相对较高(Java 8+)
         *    
         * 2. 无接口或需要继承时使用CGLIB
         *    - 需要CGLIB依赖
         *    - 不能代理final类
         *    
         * 3. 现代Spring使用
         *    - Spring Boot默认使用CGLIB
         *    - 因为CGLIB避免了类型转换问题
         */
        System.out.println("动态代理选择指南");
        System.out.println("=================");
        System.out.println("1. 有接口: 优先JDK动态代理");
        System.out.println("2. 无接口: 使用CGLIB");
        System.out.println("3. Spring Boot默认: CGLIB");
    }
}
  1. JDK动态代理

    • 基于接口(Proxy.newProxyInstance)
    • 通过InvocationHandler处理调用
    • 代理对象自动继承java.lang.reflect.Proxy
  2. CGLIB动态代理

    • 基于继承(Enhancer)
    • 通过MethodInterceptor处理调用
    • 不能代理final类和方法
  3. 应用场景

    • AOP编程(事务、日志)
    • RPC框架
    • 延迟加载
    • 权限控制
    • 性能监控
  4. 性能考虑

    • JDK代理创建对象效率高,调用时性能略低
    • CGLIB创建对象效率低,调用时性能较高
    • 现代JVM对JDK代理性能优化明显

这个完整案例涵盖了动态代理的主要用法,你可以根据实际需求选择合适的方式。

抱歉,评论功能暂时关闭!