エージェントモードProxy(ダイナミックエージェント)プログラム実行時に、反射メカニズムを用いて動的に作成

2112 ワード

JDKダイナミックエージェントを使用してエージェントオブジェクトを生成し、エージェントのみがインタフェースを実装したクラス
public class JDKProxy implements InvocationHandler {

	@Override
	public Object invoke(Object proxy, Method method, Object[] args)
			throws Throwable {
		// TODO Auto-generated method stub
		
		return null;
	}

}

Object:エージェントされるオブジェクト、クラス
Method:呼び出す方法
Object[]:メソッド呼び出しに必要なパラメータ
Proxyクラス:  Proxyクラスは、エージェントを専門とする操作クラスであり、1つ以上のインタフェースに対して実装クラスを動的に生成することができます.これにより、次の操作方法が提供されます.  public static Object newProxyInstance(ClassLoader loader, Class[] interfaces,  InvocationHandler h)   throws IllegalArgumentException  パラメータの説明:  ClassLoader loader:クラスローダクラスローダ  Class[]interfaces:すべてのインタフェースを取得  InvocationHandler h:InvocationHandlerインタフェースのサブクラスインスタンスを取得する 
Ps:クラスローダ  ProxyクラスのnewProxyInstance()メソッドにはClassLoaderクラスのインスタンスが必要です.ClassLoaderは実際にクラスローダに対応しています.Javaには主に3種類のローダがあります.  Booststrap ClassLoader:このローダはC++で作成されており、一般的に開発では見られません.  Extendsion ClassLoader:拡張クラスのロードに使用され、一般的にjrelibextディレクトリのクラスに対応します.  AppClassLoader:(デフォルト)classpathで指定されたクラスをロードし、最もよく使用されるのはローダです. 
public class JDKProxy implements InvocationHandler {

	Object target = null;
	
	public Object bind(Object target) {
		this.target = target;
		return Proxy.newProxyInstance(target.getClass().getClassLoader(), target.getClass().getInterfaces(), this);
	}
	
	@Override
	public Object invoke(Object proxy, Method method, Object[] args)
			throws Throwable {
		// TODO Auto-generated method stub
		Object result = null;
		System.out.println("begin---------------");
		result = method.invoke(target, args);
		System.out.println("end------------------");
		return result;
	}

}
ProxyクラスのnewProxyInstance()メソッドの最後のパラメータthisは、メソッドが存在するクラスがInvocationHandlerインタフェースを実装しているため、bindメソッドを使用してエージェントのインタフェース実装クラスを動的にバインドできます.
JDKProxy p = new JDKProxy();
QueryDAO q = (QueryDAO) p.bind(new QueryDAOImpl());
呼び出し
あとCGLIB、JAVASSITなどのダイナミックエージェントを実現する方法もありますが、ここでは詳しくは説明しませんが、確かに理解が難しく、あまり使われていません.最もよく使われているのはJDKのダイナミックエージェントです.