動的プロキシは、実際には、指定したすべてのインターフェースに基づいてクラスを動的に生成する java.lang.reflect.Proxy クラスです。 バイトの場合、このクラスは Proxy クラスを継承し、指定したすべてのインターフェイス (パラメーターで渡すインターフェイス配列) を実装し、指定したクラスローダーを使用します。 クラス バイトがシステムにロードされ、最終的にそのようなクラスのオブジェクトが生成され、invocationHandler、つまりすべてのインターフェイスに対応するメソッド メンバーなど、オブジェクトのいくつかの値が初期化されます。 初期化後、オブジェクトは呼び出し側クライアントに返されます。このようにして、クライアントはすべてのインターフェイスを実装する Proxy オブジェクトを取得します。分析例を参照してください:
package com.fans.common.proxy; public interface BusinessProcessor { public void processBusiness(); }
package com.fans.common.proxy; /** * 业务处理类 * @author fanshadoop * */ public class BusinessProcessorImpl implements BusinessProcessor { @Override public void processBusiness() { System.out.println("processing business....."); } }
package com.fans.common.proxy; import java.lang.reflect.InvocationHandler; import java.lang.reflect.Method; /** * 业务代理类 * @author fanshadoop * */ public class BusinessProcessorHandler implements InvocationHandler { private Object target = null; BusinessProcessorHandler(Object target) { this.target = target; } public Object invoke(Object proxy, Method method, Object[] args) throws Throwable { System.out .println("You can do something here before process your business"); Object result = method.invoke(target, args); System.out .println("You can do something here after process your business"); return result; } }
package com.fans.common.proxy; import java.lang.reflect.Field; import java.lang.reflect.Method; import java.lang.reflect.Modifier; import java.lang.reflect.Proxy; public class Test { /** * @param args */ public static void main(String[] args) { BusinessProcessorImpl bpimpl = new BusinessProcessorImpl(); BusinessProcessorHandler handler = new BusinessProcessorHandler(bpimpl); BusinessProcessor bp = (BusinessProcessor) Proxy.newProxyInstance( bpimpl.getClass().getClassLoader(), bpimpl.getClass() .getInterfaces(), handler); bp.processBusiness(); System.out.println(bp.getClass().getName()); printClassDefinition(bp.getClass()); } public static String getModifier(int modifier) { String result = ""; switch (modifier) { case Modifier.PRIVATE: result = "private"; case Modifier.PUBLIC: result = "public"; case Modifier.PROTECTED: result = "protected"; case Modifier.ABSTRACT: result = "abstract"; case Modifier.FINAL: result = "final"; case Modifier.NATIVE: result = "native"; case Modifier.STATIC: result = "static"; case Modifier.SYNCHRONIZED: result = "synchronized"; case Modifier.STRICT: result = "strict"; case Modifier.TRANSIENT: result = "transient"; case Modifier.VOLATILE: result = "volatile"; case Modifier.INTERFACE: result = "interface"; } return result; } public static void printClassDefinition(Class clz) { String clzModifier = getModifier(clz.getModifiers()); if (clzModifier != null && !clzModifier.equals("")) { clzModifier = clzModifier + " "; } String superClz = clz.getSuperclass().getName(); if (superClz != null && !superClz.equals("")) { superClz = "extends " + superClz; } Class[] interfaces = clz.getInterfaces(); String inters = ""; for (int i = 0; i < interfaces.length; i++) { if (i == 0) { inters += "implements "; } inters += interfaces[i].getName(); } System.out.println(clzModifier + clz.getName() + " " + superClz + " " + inters); System.out.println("{"); Field[] fields = clz.getDeclaredFields(); for (int i = 0; i < fields.length; i++) { String modifier = getModifier(fields[i].getModifiers()); if (modifier != null && !modifier.equals("")) { modifier = modifier + " "; } String fieldName = fields[i].getName(); String fieldType = fields[i].getType().getName(); System.out.println(" " + modifier + fieldType + " " + fieldName + ";"); } System.out.println(); Method[] methods = clz.getDeclaredMethods(); for (int i = 0; i < methods.length; i++) { Method method = methods[i]; String modifier = getModifier(method.getModifiers()); if (modifier != null && !modifier.equals("")) { modifier = modifier + " "; } String methodName = method.getName(); Class returnClz = method.getReturnType(); String retrunType = returnClz.getName(); Class[] clzs = method.getParameterTypes(); String paraList = "("; for (int j = 0; j < clzs.length; j++) { paraList += clzs[j].getName(); if (j != clzs.length - 1) { paraList += ", "; } } paraList += ")"; clzs = method.getExceptionTypes(); String exceptions = ""; for (int j = 0; j < clzs.length; j++) { if (j == 0) { exceptions += "throws "; } exceptions += clzs[j].getName(); if (j != clzs.length - 1) { exceptions += ", "; } } exceptions += ";"; String methodPrototype = modifier + retrunType + " " + methodName + paraList + exceptions; System.out.println(" " + methodPrototype); } System.out.println("}"); } }
操作結果:
You can do something here before process your business processing business..... You can do something here after process your business $Proxy0 $Proxy0 extends java.lang.reflect.Proxy implements com.fans.common.proxy.BusinessProcessor { java.lang.reflect.Method m1; java.lang.reflect.Method m3; java.lang.reflect.Method m0; java.lang.reflect.Method m2; boolean equals(java.lang.Object); java.lang.String toString(); int hashCode(); void processBusiness(); }
BusinessProcessorHandler クラスは、InvocationHandler インターフェイスの呼び出しメソッドを実装します。このクラスは、Proxy が最終的に呼び出す固定インターフェイス メソッドです。
明らかに、Proxy.newProxyInstance メソッドは次のことを行います:
1. 渡された 2 番目のパラメーター インターフェイスに基づいてクラスを動的に生成し、インターフェイスにインターフェイスを実装します。この例では、BusinessProcessor インターフェイスの processBusiness メソッドです。そしてProxyクラスを継承し、hashcode、toString、equalsの3つのメソッドを書き換えます。具体的な実装については、以下を参照してください。
ProxyGenerator.generateProxyClass(...); この例では、$Proxy0 クラス
2 が生成され、最初のパラメーターに渡された classloder を通じて新しく生成されたクラスが jvm にロードされます。 $Proxy0 クラスをロードしようとしています
3、3 番目のパラメーターを使用して $Proxy0 の $Proxy0 (InvocationHandler) コンストラクターを呼び出し、$Proxy0 のオブジェクトを作成し、interfaces パラメーターを使用してそのすべてのインターフェイスのメソッドを走査し、 Method オブジェクトを使用してオブジェクトを初期化します。メソッド メンバー変数
4、$Proxy0 のインスタンスをクライアントに返します。
もう大丈夫です。クライアントがそれをどのように調整するかを見てみましょう。そうすれば明らかになるでしょう。
1. クライアントが取得するのは$Proxy0のインスタンスオブジェクトです。 $Proxy0はBusinessProcessorを継承しているのでBusinessProcessorに変換しても問題ありません。 S BusinessProcessor BP = (BusinessProcessor) Proxy.newproxyinstance (...);
2, bp.processBusiness (); $ proxy0.processBusines () の実装は、InvocationHandler を介して invoke メソッドを呼び出します
以上が詳細な説明です。 Java ダイナミック プロキシ アプリケーションの詳細については、PHP 中国語 Web サイト (www.php.cn) をご覧ください。