JDKの動的プロキシ実装の原則の概要JDKの動的プロキシ実装の原則

プロキシオブジェクトの実行時の手順を作成します

  1. プロキシクラスのバイトコードを生成します
  2. ロードバイトコード、プロキシオブジェクトを作成します

まず、目的は、プロキシオブジェクトのメソッドは、メソッドが呼び出されたときにプロキシオブジェクトですが、また、彼らが実行する方法を増やすことができ、自然にプロキシオブジェクトを取得することで達成することだけではありません

エージェントクラスは、プロキシオブジェクトのインタフェースクラスを実装する必要があり、このように生成されたプロキシオブジェクトは、メソッド・プロキシ・オブジェクトを呼び出すことによって実行されてもよいです。したがって、プロキシクラスを作成する必要性は、インタフェースクラスのプロキシオブジェクト(反射が得られる)であります

プロキシクラスインターフェースメソッドはクラスのカスタムメソッドにユーザによって実装、したがってプロキシクラスのクラス(またはセットコンストラクタメソッド)を取得する必要があり、ユーザ定義

バイトコードをロードするため、クラスローダを取得する必要があり、プロキシ・オブジェクトからの反射によって得ることができます。

 

プロキシオブジェクトを生成するためのこのよう方法

//プロキシオブジェクトのターゲット

パブリック<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何かがない
の後に何かをします

 

おすすめ

転載: www.cnblogs.com/cai-cai777/p/11210721.html