我正在学习java动态代理,这是我的代码:
//interface Move.java
public interface Move {
public void testMove();
}
然后是实现类
public class Tank implements Move{
public void testMove() {
System.out.println("test in Tank");
}
}
接着是
import java.lang.reflect.InvocationHandler;
import java.lang.reflect.Method;
public class MoveHandler implements InvocationHandler{
private Object target;
public MoveHandler(Object target) {
this.target = target;
}
@Override
public Object invoke(Object proxy, Method method, Object[] args)
throws Throwable {
System.out.println("in MoveHandler");
Object ret;
try {
ret = method.invoke(target, args);
}catch (Exception e) {
e.printStackTrace();
throw e;
}
System.out.println("after MoveHandler");
return ret;
}
}
测试类
public class Main {
public static void main(String[] args) {
Move test = new Tank();
MoveHandler proxy = new MoveHandler(test);
Move real = (Move) Proxy.newProxyInstance(test.getClass().getClassLoader(), test.getClass().getInterfaces(), proxy);
real.testMove();
}
}
当我运行Main类时,我可以得到正确的结果。如果我将method.invoke(target, args)
更改为method.invoke(proxy, args)
,则会有数千行异常和错误。 invoke(Object proxy, Method method, Object[] args)
中参数代理的用法是什么?如何正确使用?
答案 0 :(得分:2)
proxy参数是Proxy.newProxyInstance()
返回的对象,在该对象上调用实际方法(testMove()
)。您通常不需要它,但可能需要知道代理实现的接口,例如。
在这个参数上调用方法是一个非常糟糕的主意,因为它基本上是一个递归方法调用:你在代理上调用一个方法,调用调用处理程序调用处理程序的代理上的方法调用处理程序,等
答案 1 :(得分:0)
使用Java Reflection可以在运行时创建接口的动态实现。您可以使用班级
java.lang.reflect.Proxy
执行此操作。这个类的名称就是我将这些动态接口实现称为动态代理的原因。动态代理可以用于许多不同的目的,例如数据库连接和事务管理,用于单元测试的动态模拟对象,以及其他类似AOP的方法拦截目的。
进一步解释:
传递给
proxy
方法的invoke()
参数是实现接口的动态代理对象。通常你不需要这个对象。
这是来自this tutorial,更详细地解释了这一点。