java.lang.reflect.Proxyを使ってみる

以前から「面白そうだな〜」と思っていたjava.lang.reflect.Proxyを使ってみた。


まず、プロキシに動的に実装されるfoo.bar.Fooインターフェースは以下の通り。


package foo.bar;

public interface Foo {
public String hoge(String str, int num);
public String hogehoge(String str);
}


プロキシに対するメソッドの呼び出しをハンドルするfoo.bar.MyInvocationHandlerは以下の通り。


package foo.bar;

import java.lang.reflect.InvocationHandler;
import java.lang.reflect.Method;
import java.util.Arrays;

public class MyInvocationHandler implements InvocationHandler {

public Object invoke(Object proxy, Method method, Object args)
throws Throwable {
//System.out.println(proxy);
System.out.println(method);
System.out.println(Arrays.asList(args));
return "戻り値";
}

}


で、実行クラス。ほとんどJavaDocの通り。


package foo.bar;

import java.lang.reflect.InvocationHandler;
import java.lang.reflect.Proxy;

public class Runner {

public static void main(String args) {
InvocationHandler handler = new MyInvocationHandler();
Foo f = (Foo) Proxy.newProxyInstance(Foo.class.getClassLoader(),
new Class[] { Foo.class }, handler);
System.out.println(f.hoge("文字列", 10));
System.out.println(f.hogehoge("文字列2"));
}

}


実行すると…


public abstract java.lang.String foo.bar.Foo.hoge(java.lang.String,int)
[文字列, 10]
戻り値
public abstract java.lang.String foo.bar.Foo.hogehoge(java.lang.String)
[文字列2]
戻り値
おお〜、面白い。
プロキシのメソッド呼び出しは、全部、InvocationHandler#invole()でハンドルするらしい。
なので、MyInvocationHandlerのコメントをはずしたら、無限ループでスタックオーバーフローになった。


アイデア次第でいろいろ使えるかも…