java动态代理问题

时间:2014-10-26 08:35:47

标签: java proxy

我正在学习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)中参数代理的用法是什么?如何正确使用?

2 个答案:

答案 0 :(得分:2)

proxy参数是Proxy.newProxyInstance()返回的对象,在该对象上调用实际方法(testMove())。您通常不需要它,但可能需要知道代理实现的接口,例如。

在这个参数上调用方法是一个非常糟糕的主意,因为它基本上是一个递归方法调用:你在代理上调用一个方法,调用调用处理程序调用处理程序的代理上的方法调用处理程序,等

答案 1 :(得分:0)

  

使用Java Reflection可以在运行时创建接口的动态实现。您可以使用班级java.lang.reflect.Proxy执行此操作。这个类的名称就是我将这些动态接口实现称为动态代理的原因。动态代理可以用于许多不同的目的,例如数据库连接和事务管理,用于单元测试的动态模拟对象,以及其他类似AOP的方法拦截目的。

进一步解释:

  

传递给proxy方法的invoke()参数是实现接口的动态代理对象。通常你不需要这个对象。

这是来自this tutorial,更详细地解释了这一点。