Java反射实战:动态代理基础 —— 基于反射的代理实现

动态代理是Java反射机制的核心应用之一,允许在运行时动态创建代理对象,实现对目标方法的拦截和增强。以下是基于反射的动态代理实现步骤:

1. 定义接口(目标行为规范)
// 支付接口
public interface Payment {
    void pay(int amount);
    String getPayMethod();
}

2. 实现目标类(真实对象)
// 真实支付实现
public class RealPayment implements Payment {
    @Override
    public void pay(int amount) {
        System.out.println("支付成功: ¥" + amount);
    }

    @Override
    public String getPayMethod() {
        return "银行卡支付";
    }
}

3. 创建调用处理器(核心代理逻辑)
import java.lang.reflect.InvocationHandler;
import java.lang.reflect.Method;

public class PaymentHandler implements InvocationHandler {
    private final Object target;  // 持有真实对象引用

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

    @Override
    public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {
        // 前置增强
        System.out.println("【代理拦截】开始调用: " + method.getName());
        
        // 反射调用真实方法
        Object result = method.invoke(target, args);
        
        // 后置增强
        System.out.println("【代理拦截】调用完成");
        return result;
    }
}

4. 动态生成代理对象
import java.lang.reflect.Proxy;

public class DynamicProxyDemo {
    public static void main(String[] args) {
        // 创建真实对象
        Payment realPayment = new RealPayment();
        
        // 创建调用处理器(绑定真实对象)
        PaymentHandler handler = new PaymentHandler(realPayment);
        
        // 动态生成代理对象
        Payment proxy = (Payment) Proxy.newProxyInstance(
            realPayment.getClass().getClassLoader(), // 类加载器
            realPayment.getClass().getInterfaces(),  // 实现的接口
            handler                                  // 调用处理器
        );
        
        // 通过代理对象调用方法
        proxy.pay(500);
        System.out.println("支付方式: " + proxy.getPayMethod());
    }
}

执行结果
【代理拦截】开始调用: pay
支付成功: ¥500
【代理拦截】调用完成
【代理拦截】开始调用: getPayMethod
【代理拦截】调用完成
支付方式: 银行卡支付

关键机制解析
  1. 动态代理原理
    通过Proxy.newProxyInstance()在运行时生成代理类,该类实现指定接口并重写所有方法,将方法调用转发给InvocationHandler

  2. 方法调用流程
    $$ \text{代理对象} \xrightarrow{\text{方法调用}} \text{InvocationHandler.invoke()} \xrightarrow{\text{反射}} \text{真实对象方法} $$

  3. 核心接口说明

    • InvocationHandler:代理逻辑处理器,实现invoke()方法
    • Proxy:生成代理对象的工厂类
实际应用场景
  1. AOP编程:日志记录、性能监控
  2. 事务管理:方法调用前后开启/提交事务
  3. 权限控制:方法执行前的权限校验
  4. 远程调用:RPC框架的客户端代理

重要限制:Java动态代理只能基于接口实现,无法代理普通类。若需代理类,需使用CGLIB等第三方库。

Logo

Agent 垂直技术社区,欢迎活跃、内容共建。

更多推荐