プロキシオブジェクトの実行時の手順を作成します
- プロキシクラスのバイトコードを生成します
- ロードバイトコード、プロキシオブジェクトを作成します
まず、目的は、プロキシオブジェクトのメソッドは、メソッドが呼び出されたときにプロキシオブジェクトですが、また、彼らが実行する方法を増やすことができ、自然にプロキシオブジェクトを取得することで達成することだけではありません
エージェントクラスは、プロキシオブジェクトのインタフェースクラスを実装する必要があり、このように生成されたプロキシオブジェクトは、メソッド・プロキシ・オブジェクトを呼び出すことによって実行されてもよいです。したがって、プロキシクラスを作成する必要性は、インタフェースクラスのプロキシオブジェクト(反射が得られる)であります
プロキシクラスインターフェースメソッドはクラスのカスタムメソッドにユーザによって実装、したがってプロキシクラスのクラス(またはセットコンストラクタメソッド)を取得する必要があり、ユーザ定義
バイトコードをロードするため、クラスローダを取得する必要があり、プロキシ・オブジェクトからの反射によって得ることができます。
プロキシオブジェクトを生成するためのこのよう方法
//プロキシオブジェクトのターゲット
パブリック<T> T getProxy(){ リターン(T)たとえば、Proxy.newProxyInstance(target.getClass()のgetClassLoader()//生成されたローディングプロキシクラスバイトコードのクラスローダ
target.getClassを()でgetInterfaces ()//インターフェースプロキシクラスを実装する必要がプロキシオブジェクトのクラスであることが
、この//ユーザエージェントは、方法は、定義された実装
;) }
次のように上記のフルダイナミックプロキシ実装例行われる以下のコードの完全な実装であるれる
とら
JDKの動的プロキシ実装の原則
com.lnjecit.proxyパッケージ; / ** *件名 *インタフェースに関連する抽象 * @author * @Create 2018年3月29日14時16分 ** / パブリックインターフェイステーマ{ ボイドのdoSomething(); }
新しい実装クラスRealSubject RealSubjectを作成し、インターフェイス
/ ** * RealSubject *真实主题类 * @author * @Create 2018年3月29日14時21分 ** / publicクラスRealSubjectは、件名{実装 @Override ます。public void doSomethingのを(){ System.out.printlnは( "RealSubjectは何かを「); } }
そして、プロキシクラスを作成JDKDynamicProxy java.lang.reflect.InvocationHandlerインタフェース書き換えinvokeメソッドを達成
パッケージcom.lnjecit.proxy.dynamic.jdk。 輸入java.lang.reflect.InvocationHandler。 輸入java.lang.reflect.Methodオブジェクト。 輸入java.lang.reflect.Proxyの; / ** * JDKDynamicProxy * jdkd动态代理 * * @author * @Create 2018年3月29日午後04時17 ** / JDKDynamicProxyがInvocationHandlerです{実装publicクラス のプライベートオブジェクトのターゲットを、 公共JDKDynamicProxy(オブジェクト・ターゲット){ this.target =ターゲット。 } / ** *获取被代理接口实例对象 * @param <T> * @return * / パブリック<T> T getProxy(){ リターン(T)たとえば、Proxy.newProxyInstance(target.getClass()のgetClassLoader()、target.getClass()でgetInterfaces()、本。); } @Override パブリックオブジェクトを呼び出したThrowable {スロー(オブジェクト・プロキシは、メソッドの方法は、[]引数オブジェクト) (「何かをする前に」)するSystem.out.println。 オブジェクトの結果= method.invoke(ターゲット、引数)。 System.out.println( "の後に何かをします"); 結果を返します。 } }
新しいテストクラスクライアントのテスト結果
com.lnjecit.proxyパッケージ; インポートcom.lnjecit.proxy.dynamic.jdk.JDKDynamicProxy; / ** *クライアント *クライアントのテストコード * * @author * @Create 2018年3月29日14時26 ** / publicクラスクライアント{ 公共の静的な無効メイン(文字列[] args){ //生成されたプロキシクラスのバイトコードファイルの保存 ( "真の" "sun.misc.ProxyGenerator.saveGeneratedFilesを"、))(System.getPropertiesをPUT ;. // JDK動的試験薬剤 JDKDynamicProxy件名件名新しい新=(新しい新しいRealSubject())getProxy(); subject.doSomething(); } }
出力:
前に何かをする
RealSubject何かがない
の後に何かをします