简体   繁体   English

用Java捕获方法调用

[英]Capture method calls in Java

I need to capture a method call in Java and I do not want to use JPDA or JDI; 我需要捕获Java中的方法调用,我不想使用JPDA或JDI; I want it to happen in the original JVM. 我希望它发生在原始的JVM中。

For instance: 例如:

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

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

I do not want to actually let the method execute at the time, but need to capture it and schedule it in a queue. 我不想让方法在当时执行,但需要捕获它并将其安排在队列中。 Thus, AOP will not help me in this regard. 因此,AOP在这方面不会帮助我。 I thought about proxying the method. 我想到代理方法。 Something such as: 像这样的东西:

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

Any ideas? 有任何想法吗? Thanks so much in advance. 非常感谢提前。

You can use a technique called Dynamic Proxies in Java. 您可以在Java中使用一种名为Dynamic Proxies的技术。 They are described in detail in the following document: Dynamic Proxies 它们在以下文档中有详细描述: 动态代理

The solution for your problem would then be (with little changes necessary): 那么你的问题的解决方案就是(只需要很少的改动):

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;
    }
}

Then construct a EnqueueProxy for an implementation of the A interface and call the m method: 然后构造一个EnqueueProxy用于A接口的实现并调用m方法:

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

看起来你也会对Callable的队列感到满意。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM