java.lang.reflect.Proxyを使ってみる その2

プロキシを使った動的なメソッドの追加を考えてみた。


メソッドが追加されるクラスは次の通り。Fooインターフェースを実装する。


package foo.bar;

public class FooImpl implements Foo {

public void func1() {
System.out.println("func1() called.");
}

public void func2() {
System.out.println("func2() called.");
}

}


追加するメソッド、func3()を定義するインターフェースは以下の通り。


package foo.bar;

public interface Bar {

public void func3();

}


InvocationHandlerは以下のように実装。


package foo.bar;

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

public class MyInvocationHandler implements InvocationHandler {

private Foo foo = null;

private Bar bar = null;

public MyInvocationHandler(Foo foo, Bar bar) {
this.foo = foo;
this.bar = bar;
}

public Object invoke(Object proxy, Method method, Object args)
throws Throwable {
if (method.getName().equals("func3")) {
return method.invoke(bar, args);
} else {
return method.invoke(foo, args);
}
}

}


で、実行クラス。


package foo.bar;

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

public class Runner {

public static void main(String args) {
Foo foo = new FooImpl();

InvocationHandler handler = new MyInvocationHandler(foo, new Bar() {
public void func3() {
System.out.println("func3() called.");
}
});

Object foobar = Proxy.newProxyInstance(Foo.class.getClassLoader(),
new Class[] { Foo.class, Bar.class }, handler);
((Foo) foobar).func1();
((Foo) foobar).func2();
((Bar) foobar).func3();
}

}


実行結果は次の通り。


func1() called.
func2() called.
func3() called.