从 0 学 Java(22):反射实战:动态代理的基础 —— 基于反射的代理实现
·
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
【代理拦截】调用完成
支付方式: 银行卡支付
关键机制解析
-
动态代理原理
通过Proxy.newProxyInstance()在运行时生成代理类,该类实现指定接口并重写所有方法,将方法调用转发给InvocationHandler -
方法调用流程
$$ \text{代理对象} \xrightarrow{\text{方法调用}} \text{InvocationHandler.invoke()} \xrightarrow{\text{反射}} \text{真实对象方法} $$ -
核心接口说明
InvocationHandler:代理逻辑处理器,实现invoke()方法Proxy:生成代理对象的工厂类
实际应用场景
- AOP编程:日志记录、性能监控
- 事务管理:方法调用前后开启/提交事务
- 权限控制:方法执行前的权限校验
- 远程调用:RPC框架的客户端代理
重要限制:Java动态代理只能基于接口实现,无法代理普通类。若需代理类,需使用CGLIB等第三方库。
更多推荐
所有评论(0)