java23デザインパターン---プロキシモード

**

プロキシモードとは何ですか?

**
プロキシモードを定義する:オブジェクトへのプロキシモードでは、プロキシオブジェクト、元のオブジェクトを参照することによって制御さプロキシオブジェクトを提供します。人気話す代理店モデルは、共通の仲介で、私たちの生活です。

説明するための例を与えるために:あなたは私は車の独自のソースを見つけることができますが、中古車、車のシリーズを購入したいの品質検査や他の遷移過程を行うと言うが、これは本当に私の時間とエネルギーの無駄だった場合。私はちょうど私がそんなに余分なことを行うべき理由だけで車を購入したいですか?私は仲介会社を通じて車を買うようになったので、彼らは私が車の所有プロセスの転送を処理支援するために、車の源を見つけるために私に来て、私はそれを支払う、自分の好きな車を選択するだけの責任です。次のように図表現しました。

なぜプロキシモードを使うのか?

仲介アイソレーション:いくつかのケースでは、クライアントクラスは望んでいないか、または直接デリゲートオブジェクトを参照することはできません、プロキシクラスのオブジェクトは、クライアントとデリゲートオブジェクトクラス間の仲介の役割を果たすことができ、プロキシクラスとデリゲートクラスの実装であります同じインターフェイス。
開閉原理は、増加した機能は:仲介プロキシクラスの顧客クラスと委譲クラスであることに加えて、我々はまた、追加機能を追加するために、プロキシクラスでデリゲートの機能を拡張することができ、我々は唯一のプロキシクラスを変更することなく、これを実行する必要がありますその後、コード設計を開閉の原則に沿って、委譲クラスを変更します。デリゲートメッセージ、フィルタメッセージ、デリゲートへのメッセージを転送し、返された結果のその後の取り扱いの前処理のためにとのように主要な責任を代行。演技のクラス自体は、実際にサービスを実現しませんが、委譲クラスを呼び出すことにより、同じ相関法は、特定のサービスを提供します。実際のビジネス機能が委譲クラスによって実装されていますが、ビジネス機能の実行前と後にいくつかの公共サービスを追加することができます。たとえば、私たちは、プロジェクトのキャッシュに参加し、これらの機能を記録したい、我々は完全にプロキシクラス、およびパッケージ化された委譲クラスをオープンする必要はありませんを使用することができます。
代理店モデルは何ですか?
ブローカーモード
我々は、エージェントを達成するために、さまざまな異なる方法があります。静的プロキシ、動的な代理店:代理店に従い、期間を分類するために作成された場合、それは2つのタイプに分けることができます。静的プロキシは、プログラマによって作成されたか、特定のツールが自動的にコンパイルしてソースコードを生成します。プログラマが実行する前に、プロキシクラスの.classファイルが作成されました。ダイナミックプロキシは動的にプログラム実行されているに反射によって作成されます。

1.静的プロキシ

ステップ1:サービスクラスのインタフェースを作成します。

 1 package main.java.proxy;
 2 
 5 /**
 6  * @Auther: 1543057945
 7  * @Description:
 8  * @Date: 22:43 2019/5/9/18
 9  */
 8 public interface BuyHouse {
 9     void buyHosue();
10 }

ステップ2:サービス・インタフェースの実装

コードをコピー

 1 import main.java.proxy.BuyHouse;
 2 
 5 /**
 6  * @Auther: 1543057945
 7  * @Description:
 8  * @Date: 22:43 2019/5/9/18
 9  */
 8 public class BuyHouseImpl implements BuyHouse {
 9 
10     @Override
11     public void buyHosue() {
12         System.out.println("我要买房");
13     }
14 }

ステップ3:プロキシクラスを作成します。

1 package main.java.proxy.impl;
 2 
 3 import main.java.proxy.BuyHouse;
 4 
 5 /**
 6  * @Auther: 1543057945
 7  * @Description:
 8  * @Date: 22:43 2019/5/9/18
 9  */
10 public class BuyHouseProxy implements BuyHouse {
11 
12     private BuyHouse buyHouse;
13 
14     public BuyHouseProxy(final BuyHouse buyHouse) {
15         this.buyHouse = buyHouse;
16     }
17 
18     @Override
19     public void buyHosue() {
20         System.out.println("买房前准备");
21         buyHouse.buyHosue();
22         System.out.println("买房后装修");
23 
24     }
25 }

第四段階:書き込みテストクラス

import main.java.proxy.impl.BuyHouseImpl;
import main.java.proxy.impl.BuyHouseProxy;

 5 /**
 6  * @Auther: 1543057945
 7  * @Description:
 8  * @Date: 22:43 2019/5/9/18
 9  */
public class ProxyTest {
    public static void main(String[] args) {
        BuyHouse buyHouse = new BuyHouseImpl();
        buyHouse.buyHosue();
        BuyHouseProxy buyHouseProxy = new BuyHouseProxy(buyHouse);
        buyHouseProxy.buyHosue();
    }
}

静的プロキシの概要:

利点:開閉の原則に準拠して、対象物の拡張に行うことができます。

短所:私たちは、それぞれのサービスプロキシクラス、重いワークロードと管理が難しいために作成する必要がありました。インタフェース中に変更すると、プロキシクラスはそれに応じて改正する必要があります。

**

2.動的プロキシ

**
  動的プロキシでは、我々は必要にもはや手動でプロキシクラスを作成し、我々はそれだけで動的なプロセッサを記述する必要がありません。私たちは再び実行したときにJDKするための動的プロキシオブジェクトを作成する場合はTrue。

**イタリックスタイル最初のステップ:書き込みダイナミックプロセッサ

 1 package main.java.proxy.impl;
 2 
 3 import java.lang.reflect.InvocationHandler;
 4 import java.lang.reflect.Method;
 5 
 5 /**
 6  * @Auther: 1543057945
 7  * @Description:
 8  * @Date: 22:43 2019/5/9/18
 9  */
11 public class DynamicProxyHandler implements InvocationHandler {
12 
13     private Object object;
14 
15     public DynamicProxyHandler(final Object object) {
16         this.object = object;
17     }
18 
19     @Override
20     public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {
21         System.out.println("买房前准备");
22         Object result = method.invoke(object, args);
23         System.out.println("买房后装修");
24         return result;
25     }
26 }

ステップ2:書き込みテストクラス

 1 package main.java.proxy.test;
 2 
 3 import main.java.proxy.BuyHouse;
 4 import main.java.proxy.impl.BuyHouseImpl;
 5 import main.java.proxy.impl.DynamicProxyHandler;
 6 
 7 import java.lang.reflect.Proxy;
 8 
 5 /**
 6  * @Auther: 1543057945
 7  * @Description:
 8  * @Date: 22:43 2019/5/9/18
 9  */
14 public class DynamicProxyTest {
15     public static void main(String[] args) {
16         BuyHouse buyHouse = new BuyHouseImpl();
17         BuyHouse proxyBuyHouse = (BuyHouse) Proxy.newProxyInstance(BuyHouse.class.getClassLoader(), new
18                 Class[]{BuyHouse.class}, new DynamicProxyHandler(buyHouse));
19         proxyBuyHouse.buyHosue();
20     }
21 }

コードのコピー
たとえば、Proxy.newProxyInstance()メソッドは、3つのパラメータを取ることを注意:

クラスローダローダは:指定したクラスローダを使用して、現在のターゲット・オブジェクトは、ローダは、固定され得ることである
<?>:インタフェースのタイプは、ジェネリック型チェックアウト使用し、ターゲットの目的を達成するために指定するクラス[]インターフェイス
のInvocationHandlerを:指定ダイナミックプロセッサターゲットオブジェクトの実行メソッドは、メソッド、イベントハンドラトリガーする際に
、動的プロキシの概要を:静的エージェントに比べものの、ビジネスインタフェースへの依存を減らすの結合の程度を削減しながら、エージェントが大幅に、私たちの開発タスクのダイナミックを低減します。そのデザインはこれを後悔する運命にあるので、しかしある時後悔の少しが、まだある、それはまだ束縛を振り払うことができないだけで、インタフェースエージェントをサポートしています。リコール継承グラフ動的に生成されたプロキシクラスつまり、彼らはプロキシと呼ばれる共通の親クラスを持つように運命づけられています。これらの動的プロキシクラスに宛てたJavaの継承メカニズムJavaでは多重継承は、自然界では動作しませんので、動的プロキシクラスを達成することができませんでした。多くのバーの理由がありますが、一つは、プロキシクラスの必要性を否定することができますが、同じようにそのサポート動的プロキシクラスより良い形を信じるためにいくつかの理由があります。インタフェースとクラスの部門は、これは非常に明白ではありませんが、Javaでとても洗練になること。メソッドの宣言だけが定義されてから検討するかどうか、2のハイブリッドが存在している場合は、その名前は抽象クラスです。要約動的プロキシクラスを達成するため、私はそれが本質的な価値を持っていると信じています。また、永遠に逃したから、彼らは任意のインタフェースおよび動的なプロキシを実装していますので、いくつかは、歴史の授業で余っがあります。非常に多く、私は少し後悔しなければなりませんでした。しかし、それは素晴らしいではありませんという意味ではありません完璧ではない、偉大な性質は、のJavaの動的プロキシは、ランクとファイルの例です。

**

3.CGLIBエージェント

**
JDKダイナミックプロキシクラスがインタフェースで定義されたビジネス・メソッドを実装する必要があり、何のクラスのためのインタフェース、およびどのようにCGLIBを必要として動的プロキシを、達成することはありません。バイトコード技術の一番下でCGLIBは、原則的には、クラスのバイトコード技術のサブクラスを作成することで、インターセプトのメソッド呼び出しの傍受技術は、すべてのサブクラスで親クラスのメソッドは、クロス織りロジックを流れ。しかし、継承を使用するので、それは最終的に、プロキシクラスに変更することはできません。JDKダイナミックプロキシエージェントは動的であり、CGLIBは春AOPの基本です。

ステップ1:プロキシクラスのCGLIBを作成します。

 1 package dan.proxy.impl;
 2 
 3 import net.sf.cglib.proxy.Enhancer;
 4 import net.sf.cglib.proxy.MethodInterceptor;
 5 import net.sf.cglib.proxy.MethodProxy;
 6 
 7 import java.lang.reflect.Method;
 8 
 5 /**
 6  * @Auther: 1543057945
 7  * @Description:
 8  * @Date: 22:43 2019/5/9/18
 9  */
14 public class CglibProxy implements MethodInterceptor {
15     private Object target;
16     public Object getInstance(final Object target) {
17         this.target = target;
18         Enhancer enhancer = new Enhancer();
19         enhancer.setSuperclass(this.target.getClass());
20         enhancer.setCallback(this);
21         return enhancer.create();
22     }
23 
24     public Object intercept(Object object, Method method, Object[] args, MethodProxy methodProxy) throws Throwable {
25         System.out.println("买房前准备");
26         Object result = methodProxy.invoke(object, args);
27         System.out.println("买房后装修");
28         return result;
29     }
30 }

ステップ2:テストクラスを作成します。

 1 package dan.proxy.test;
 2 
 3 import dan.proxy.BuyHouse;
 4 import dan.proxy.impl.BuyHouseImpl;
 5 import dan.proxy.impl.CglibProxy;
 6 
 5 /**
 6  * @Auther: 1543057945
 7  * @Description:
 8  * @Date: 22:43 2019/5/9/18
 9  */
12 public class CglibProxyTest {
13     public static void main(String[] args){
14         BuyHouse buyHouse = new BuyHouseImpl();
15         CglibProxy cglibProxy = new CglibProxy();
16         BuyHouseImpl buyHouseCglibProxy = (BuyHouseImpl) cglibProxy.getInstance(buyHouse);
17         buyHouseCglibProxy.buyHosue();
18     }
19 }

CGLIBエージェントの要約:高性能ダイナミックプロキシJDKが作成したよりも動的プロキシオブジェクトCGLIBを作成するために、オブジェクトが、時間はそれがはるかにJDKよりもプロキシオブジェクトCGLIBを作成するのにかかります。JDKの方法を使用してその逆CGLIBを持つオブジェクト権利、およびバイスがより適切であることをので、一つのケースのために頻繁にターゲットを作成する必要はありません。それが動的に作成されるためとCGLIB方法ので、最終的な方法のためのサブクラスでは、エージェントを変更することはできません。

公開された34元の記事 ウォンの賞賛6 ビュー3659

おすすめ

転載: blog.csdn.net/qq_35986709/article/details/90321375