← 返回首页

Java动态代理深入实战

📂 java ⏱ 4 min 703 words

Java动态代理深入实战

代理工厂模式

public class ProxyFactory {
    private static final Map<Class<?>, Object> proxyCache = new ConcurrentHashMap<>();

    @SuppressWarnings("unchecked")
    public static <T> T createProxy(T target, Interceptor... interceptors) {
        List<Interceptor> interceptorList = Arrays.asList(interceptors);

        return (T) Proxy.newProxyInstance(
            target.getClass().getClassLoader(),
            target.getClass().getInterfaces(),
            (proxy, method, args) -> {
                Invocation invocation = new Invocation(target, method, args);
                return executeInterceptors(invocation, interceptorList, 0);
            }
        );
    }

    private static Object executeInterceptors(Invocation invocation,
            List<Interceptor> interceptors, int index) throws Throwable {
        if (index >= interceptors.size()) {
            return invocation.proceed();
        }
        Interceptor interceptor = interceptors.get(index);
        return interceptor.intercept(() ->
            executeInterceptors(invocation, interceptors, index + 1)
        );
    }
}

多层代理

public interface LogInterceptor extends Interceptor {
    @Override
    default Object intercept(Invocation invocation) throws Throwable {
        System.out.println("[LOG] Before: " + invocation.getMethod().getName());
        Object result = invocation.proceed();
        System.out.println("[LOG] After: " + invocation.getMethod().getName());
        return result;
    }
}

public interface CacheInterceptor extends Interceptor {
    private static final Map<String, Object> cache = new ConcurrentHashMap<>();

    @Override
    default Object intercept(Invocation invocation) throws Throwable {
        String key = invocation.getMethod().getName() + Arrays.toString(invocation.getArgs());
        if (cache.containsKey(key)) {
            System.out.println("[CACHE] 命中缓存: " + key);
            return cache.get(key);
        }
        Object result = invocation.proceed();
        cache.put(key, result);
        System.out.println("[CACHE] 写入缓存: " + key);
        return result;
    }
}

// 使用
UserService service = ProxyFactory.createProxy(
    new UserServiceImpl(),
    new LogInterceptor() {},
    new CacheInterceptor() {}
);

基于注解的代理

@Target(ElementType.METHOD)
@Retention(RetentionPolicy.RUNTIME)
public @interface Retry {
    int maxAttempts() default 3;
    long delay() default 1000;
}

public class RetryInterceptor implements InvocationHandler {
    private Object target;

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

    @Override
    public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {
        Retry retry = method.getAnnotation(Retry.class);
        if (retry == null) {
            return method.invoke(target, args);
        }

        int maxAttempts = retry.maxAttempts();
        long delay = retry.delay();
        Exception lastException = null;

        for (int i = 0; i < maxAttempts; i++) {
            try {
                return method.invoke(target, args);
            } catch (Exception e) {
                lastException = e;
                System.out.println("重试 " + (i + 1) + "/" + maxAttempts);
                if (i < maxAttempts - 1) {
                    Thread.sleep(delay);
                }
            }
        }
        throw lastException;
    }
}

public interface ExternalService {
    @Retry(maxAttempts = 3, delay = 500)
    String fetchData(String url);
}

public class ExternalServiceImpl implements ExternalService {
    private int attempt = 0;

    @Override
    public String fetchData(String url) {
        attempt++;
        if (attempt < 3) {
            throw new RuntimeException("连接失败");
        }
        return "数据: " + url;
    }
}

动态代理实现事务管理

public interface TransactionInterceptor extends Interceptor {
    @Override
    default Object intercept(Invocation invocation) throws Throwable {
        Transaction tx = null;
        try {
            tx = beginTransaction();
            Object result = invocation.proceed();
            commitTransaction(tx);
            return result;
        } catch (Exception e) {
            rollbackTransaction(tx);
            throw e;
        }
    }

    private static Transaction beginTransaction() {
        System.out.println("开启事务");
        return new Transaction();
    }

    private static void commitTransaction(Transaction tx) {
        System.out.println("提交事务");
    }

    private static void rollbackTransaction(Transaction tx) {
        System.out.println("回滚事务");
    }
}

class Transaction {}

性能对比

public class ProxyPerformanceTest {
    public static void main(String[] args) throws Exception {
        UserService real = new UserServiceImpl();
        UserService jdkProxy = ProxyFactory.createProxy(real, invocation -> {
            return invocation.proceed();
        });
        UserService cglibProxy = CglibInterceptor.createProxy(real);

        int iterations = 1000000;

        // 基准测试
        long start = System.nanoTime();
        for (int i = 0; i < iterations; i++) {
            real.getUser(i);
        }
        long realTime = System.nanoTime() - start;

        start = System.nanoTime();
        for (int i = 0; i < iterations; i++) {
            jdkProxy.getUser(i);
        }
        long jdkTime = System.nanoTime() - start;

        start = System.nanoTime();
        for (int i = 0; i < iterations; i++) {
            cglibProxy.getUser(i);
        }
        long cglibTime = System.nanoTime() - start;

        System.out.println("直接调用: " + realTime / 1000000 + "ms");
        System.out.println("JDK代理: " + jdkTime / 1000000 + "ms");
        System.out.println("CGLIB代理: " + cglibTime / 1000000 + "ms");
    }
}

实际应用场景

// 1. 日志记录
public class LoggingHandler implements InvocationHandler {
    private Object target;
    private Logger logger = LoggerFactory.getLogger(target.getClass());

    @Override
    public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {
        logger.info("调用方法: {}", method.getName());
        Object result = method.invoke(target, args);
        logger.info("方法返回: {}", result);
        return result;
    }
}

// 2. 权限控制
public class AuthHandler implements InvocationHandler {
    private Object target;

    @Override
    public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {
        if (!hasPermission(method)) {
            throw new SecurityException("无权限访问: " + method.getName());
        }
        return method.invoke(target, args);
    }
}

// 3. 缓存代理
public class CacheHandler implements InvocationHandler {
    private Object target;
    private Cache<String, Object> cache = Caffeine.newBuilder()
        .maximumSize(1000)
        .expireAfterWrite(Duration.ofMinutes(10))
        .build();

    @Override
    public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {
        String key = method.getName() + ":" + Arrays.toString(args);
        return cache.get(key, k -> {
            try {
                return method.invoke(target, args);
            } catch (Exception e) {
                throw new RuntimeException(e);
            }
        });
    }
}

总结

动态代理是Java实现AOP的核心技术。通过组合多个拦截器,可以构建灵活的中间件框架。理解代理原理对于使用Spring等框架至关重要。