動的プロキシは、実際には、指定したすべてのインターフェースに基づいてクラスを動的に生成する 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) をご覧ください。

ホットAIツール

Undresser.AI Undress
リアルなヌード写真を作成する AI 搭載アプリ

AI Clothes Remover
写真から衣服を削除するオンライン AI ツール。

Undress AI Tool
脱衣画像を無料で

Clothoff.io
AI衣類リムーバー

AI Hentai Generator
AIヘンタイを無料で生成します。

人気の記事

ホットツール

ドリームウィーバー CS6
ビジュアル Web 開発ツール

AtomエディタMac版ダウンロード
最も人気のあるオープンソースエディター

ゼンドスタジオ 13.0.1
強力な PHP 統合開発環境

SublimeText3 Mac版
神レベルのコード編集ソフト(SublimeText3)

DVWA
Damn Vulnerable Web App (DVWA) は、非常に脆弱な PHP/MySQL Web アプリケーションです。その主な目的は、セキュリティ専門家が法的環境でスキルとツールをテストするのに役立ち、Web 開発者が Web アプリケーションを保護するプロセスをより深く理解できるようにし、教師/生徒が教室環境で Web アプリケーションを教え/学習できるようにすることです。安全。 DVWA の目標は、シンプルでわかりやすいインターフェイスを通じて、さまざまな難易度で最も一般的な Web 脆弱性のいくつかを実践することです。このソフトウェアは、
