动态代理有两种实现方式:
1. 基于接口实现动态代理:JDK动态代理
2. 基于继承实现动态代理:Cglib、Javassist动态代理(尚且不会)
本文目标:动态代理一个计算器功能
第一步:创建接口 ArithmeticCalculator.java:
public interface ArithmeticCalculator {
public int add(int i, int j);
public int sub(int i, int j);
public int mul(int i, int j);
public int div(int i, int j);
}
第二步:创建要被代理的类的具体实现 ArithmeticCalculatorImpl.java:
public class ArithmeticCalculatorImpl implements ArithmeticCalculator {
@Override
public int add(int i, int j) {
int result = i + j;
return result;
}
@Override
public int sub(int i, int j) {
int result = i - j;
return result;
}
@Override
public int mul(int i, int j) {
int result = i * j;
return result;
}
@Override
public int div(int i, int j) {
int result = i / j;
return result;
}
}
第三步:生成代理对象:
ArithmeticCalculatorProxy.java
实现动态代理需要清楚三个问题:
目标对象;
如何获取代理对象;
代理要做什么
//目标对象
private ArithmeticCalculator target;
public ArithmeticCalculatorProxy(ArithmeticCalculator target) {
this.target = target;
}
获取代理对象的方法:
在获取代理对象时,采用的方法是调用Proxy类的newProxyInstance方法:
public static Object newProxyInstance(ClassLoader loader, Class<?>[] interfaces, InvocationHandler h)
ClassLoader loader = target.getClass().getClassLoader();
Class[] interfaces = target.getClass().getInterfaces();
InvocationHandler h的实现为匿名内部类:
new InvocationHandler() {
public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {
String methodName = method.getName();
//记录日志
System.out.println("LoggingProxy==> The method " + methodName + " begin with "+ Arrays.asList(args));
Object result = method.invoke(target, args); //目标对象执行目标方法。相当于执行ArithmeticCalculatorImpl中的+-*/
//记录日志
System.out.println("LoggingProxy==> The method " + methodName + " ends with "+ result);
return result;
}
}
测试函数:
运行结果: