DynamicProxy
簡単に。
1)InvocationHandlerの実装クラスを作る
public class InvocationHandlerPrintMethodName implements InvocationHandler {
public Object invoke(Object proxy, Method method, Object[] args) throws Throwable{
System.out.println(proxy.getClass() + "#" + method.getName());
return null;
}
}
2)インタフェースを作成
public interface Foo{
public void foo();
}
public interface Bar{
public String bar();
}
3)2)を実装した動的プロキシを作って呼び出す(実態はInvocationHandlerPrintMethodName)
public static void main(String args[]) throws Exception{
Object o = Proxy.newProxyInstance(
ClassLoader.getSystemClassLoader(),
new Class<?>[]{Foo.class,Bar.class},
new InvocationHandlerPrintMethodName());
System.out.println(o instanceof Foo);
System.out.println(o instanceof Bar);
System.out.println(o instanceof String);
Foo foo = (Foo)o;
foo.foo();
Bar bar = (Bar)o;
bar.bar();
}
◆動的プロキシを使ったAspect
フィルターにすればいい。
public interface Foo{
public void foo();
}
public class FooImpl implements Foo{
public void foo(){
System.err.println("foo");
}
}
public class InvocationHandlerLogging implements InvocationHandler {
private Object adaptee ;
public InvocationHandlerLogging (Object adaptee){
this.adaptee = adaptee;
}
public Object invoke(Object proxy, Method method, Object[] args) throws Throwable{
System.out.println("before : " + proxy.getClass() + "#" + method.getName());
Method realMethod = adaptee.getClass().getMethod(method.getName(),getType(args));
Object retVal = method.invoke(adaptee,args);
System.out.println("after : " + proxy.getClass() + "#" + method.getName());
return retVal;
}
private Class[] getType(Object[] objects){
if(objects == null) return null;
Class[] ret = new Class[objects.length];
for (int j = 0; j < objects.length; j++) {
Object object = objects[j];
ret[j] = object.getClass();
}
return ret;
}
}
これを汎用的にするともっといい感じになる。
//InvocationHandlerのフィルタパターン
package [[annotation]].proxy;
import java.lang.reflect.InvocationHandler;
import java.lang.reflect.Method;
public abstract class InvocationHandlerAdapter implements InvocationHandler {
public abstract void preInvoke(Object proxy, Method method, Object[] args) throws Throwable;
public abstract Object postInvoke(Object proxy, Method method, Object[] args,Object retVal) throws Throwable;
public InvocationHandler adaptee = null;
public InvocationHandlerAdapter(InvocationHandler adaptee){
this.adaptee = adaptee;
}
public Object invoke(Object proxy, Method method, Object[] args) throws Throwable{
preInvoke(proxy, method, args);
Object retVal = adaptee.invoke(proxy, method, args);
return postInvoke(proxy, method, args, retVal);
}
}
//実際に呼び出される実態を呼び出す人
package annotation.proxy;
import java.lang.reflect.InvocationHandler;
import java.lang.reflect.Method;
public class InvocationHandlerImpl implements InvocationHandler{
Object object = null;
public InvocationHandlerImpl(Object object){
this.object = object;
}
@Override
public Object invoke(Object proxy, Method method, Object[] args) throws Throwable{
Method realMethod = object.getClass().getMethod(method.getName(), getType(args));
realMethod.setAccessible(true);
return realMethod.invoke(object,args);
}
private Class[] getType(Object[] objects){
if(objects == null) return null;
Class[] ret = new Class[objects.length];
for (int j = 0; j < objects.length; j++) {
Object object = objects[j];
ret[j] = object.getClass();
}
return ret;
}
}
最終更新:2008年10月07日 00:10