Захват методов вызова в Java - PullRequest
8 голосов
/ 25 января 2011

Мне нужно захватить вызов метода в 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();
  }
}

Я не хочу на самом деле разрешать выполнение метода в данный момент, но нужно записать и запланироватьв очереди.Таким образом, АОП не поможет мне в этом отношении.Я думал о проксировании метода.Что-то типа:

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

Есть идеи?Большое спасибо заранее.

Ответы [ 2 ]

15 голосов
/ 25 января 2011

Вы можете использовать технику под названием Dynamic Proxies в Java.Они подробно описаны в следующем документе: Динамические прокси

Тогда будет решено (с небольшими изменениями) решение вашей проблемы:

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 голос
/ 25 января 2011

Похоже, вы также были бы довольны очередью Возможность вызова с.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...