アットウィキロゴ

動的Proxy

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
ツールボックス

下から選んでください:

新しいページを作成する
ヘルプ / FAQ もご覧ください。