2011-01-25 18 views
8

Javaでメソッド呼び出しをキャプチャする必要があり、JPDAまたはJDIを使用したくありません。私は元のJVMでそれが発生したい。例えばJavaでのメソッド呼び出しのキャプチャ

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(){} 
} 

アイデアをお持ちですか?事前にありがとうございます。

答えて

14

Javaの動的プロキシと呼ばれる手法を使用できます。これらは、以下の文献に詳細に記載されている:あなたの問題のため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; 
    } 
} 

そして、Aインタフェースとコールの実装のためのEnqueueProxyを構築しますmメソッド:

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

しかし、この優れた応答は、概念的には、プロキシー**は** AOPの実装であるという事実によって弱体化するかもしれません。 – Riduidel

1

Callableのキューにも満足しているようです。

+0

マルチコアプラットフォーム上の異なるコアで同時にメソッド呼び出しを実行するかどうかはわかりませんので、実際は難しいです。ありがとう。 – nobeh

+0

これは、並行処理とは何の関係もなく、単に計算をラップしているだけです。つまり、run()と呼ばれ、「invoke()」ではなく)です。後であなた自身。 – ShiDoiSi

関連する問題