用Java捕获方法调用

时间:2011-01-25 14:33:38

标签: java methods

我需要用Java捕获方法调用,我不想使用JPDA或JDI;我希望它发生在最初的JVM中。

例如:

public class A {
  public void m() {}
}

public class Main {
  public static void main(String[] args) {
    A a = new A();
    a.m();
  }
}

我不想让该方法在当时执行,但需要捕获它并将其安排在队列中。因此,AOP在这方面不会帮助我。我想过代理这个方法。例如:

public class A {
  public void m() {
     methodQueue.add(new MethodInvocation() {
          public void invoke() {m_orig();}
     });
  }
  private void m_orig(){}
}

有什么想法吗?非常感谢提前。

2 个答案:

答案 0 :(得分:15)

您可以在Java中使用一种名为Dynamic Proxies的技术。它们在以下文档中详细描述:Dynamic Proxies

您的问题的解决方案将是(几乎不需要更改):

public interface A { void m(); }

public class AImpl implements A { public void m() {} }

public class EnqueueProxy implements java.lang.reflect.InvocationHandler {

    private Object obj;

    public static Object newInstance(Object obj) {
        return java.lang.reflect.Proxy.newProxyInstance(
            obj.getClass().getClassLoader(),
            obj.getClass().getInterfaces(),
            new EnqueueProxy(obj));
    }

    private EnqueueProxy(Object obj) {
        this.obj = obj;
    }

    public Object invoke(Object proxy, Method m, Object[] args) throws Throwable {
        try {
            MethodQueue mq = ... // get the queue from where you want
            mq.add(new MethodInvocation(obj, m, args)
        } catch (InvocationTargetException e) {
            throw e.getTargetException();
        } catch (Exception e) {
            throw new RuntimeException("unexpected invocation exception: " + e.getMessage());
        }
            return null;
    }
}

然后构造一个EnqueueProxy用于A接口的实现并调用m方法:

A a = (A) EnqueueProxy.newInstance(new AImpl());
a.m();

答案 1 :(得分:1)

看起来你也会对Callable s。

的队列感到满意