プログラムが実行される前にプロキシクラスが既に存在する場合、このプロキシメソッドは静的プロキシと呼ばれます。この場合、プロキシクラスは通常、Javaコードで定義されます。通常、静的プロキシのプロキシクラスとデリゲートクラスは、同じインターフェイスを実装するか、同じ親クラスから派生しています。
1。概要
1。エージェントとは何ですか
WeChatのエージェントは、製造業者に代わって商品を販売しているだけであり、メーカーはエージェントを「委託」して商品を販売することを知っています。 WeChatのビジネスエージェントに関しては、まず、彼らから物を購入するとき、私たちは通常、メーカーが誰であるか、つまり「コミッショナー」が私たちには見えないことを知りません。第二に、WeChatのビジネスエージェントは、主に友人のサークルの人々を顧客として標的にします。これは、メーカーの顧客グループの「フィルター」に相当します。さらに、マイクロビジネスエージェントとメーカーを抽象化します。前者はエージェントクラスとして抽象化することができ、後者は代表クラス(エージェントクラス)として抽象化することができます。プロキシを使用することにより、通常、2つの利点があり、言及したマイクロビジネスエージェントの2つの特性に対応できます。
アドバンテージ1:デリゲートクラスの実装を隠すことができます。
アドバンテージ2:クライアントとデリゲートクラスの間のデカップリングを実現でき、デリゲートクラスコードを変更せずに追加の処理を行うことができます。
2。静的プロキシ
プログラムが実行される前にプロキシクラスが既に存在する場合、このプロキシメソッドは静的プロキシと呼ばれます。この場合、プロキシクラスは通常、Javaコードで定義されます。通常、静的プロキシのプロキシクラスとデリゲートクラスは、同じインターフェイスを実装するか、同じ親クラスから派生しています。以下に、ベンダークラスを使用してメーカーとBusinessAgentクラスを表して、マイクロビジネスエージェントを表して静的エージェントの簡単な実装を導入します。代表団クラスとプロキシクラスの両方がSellインターフェイスを実装します。販売インターフェイスの定義は次のとおりです。
パブリックインターフェイスsell {void sell(); void ad(); }ベンダークラスの定義は次のとおりです。パブリッククラスベンダーはsell {public void sell(){system.out.println( "in sell method"); } public void ad(){system、out.println( "ad method")}}プロキシクラスBusinessAgentの定義は次のとおりです。
パブリッククラスベンダーはsell {public void sell(){system.out.println( "in sell method"); } public void ad(){system、out.println( "ad method")}} BusinessAgentクラスの定義から、エージェントクラスがデリゲートクラスへの参照を保持できるように、集計を通じて静的エージェントを実装できることを理解できます。
以下にこの要件を考えてみましょう。フィルタリング機能をベンダークラスに追加し、大学生のみに商品を販売します。静的プロキシを通じて、ベンダークラスのコードを変更せずに達成できます。 BusinessAgentクラスの販売方法に判断を追加する必要がありますが、次のとおりです。
Public Class BusinessAgentはSell {... public void sell(){if(iscollegestudent()){vendor.sell(); }} ...}これは、上記のプロキシを使用することの2番目の利点に対応します。クライアントとデリゲートクラスの間の分離を実現でき、デリゲートクラスコードを変更せずに追加の処理を行うことができます。静的プロキシの制限は、実行する前にプロキシクラスを書く必要があることです。実行時にプロキシクラスを生成する動的プロキシ方法の導入に焦点を当てましょう。
2。動的エージェント
1。動的プロキシとは何ですか
プログラムが実行されたときにプロキシクラスによって作成されたプロキシメソッドは、動的プロキシと呼ばれます。つまり、この場合、プロキシクラスはJavaコードで定義されていませんが、Javaコードの「指示」に基づいて実行時に動的に生成されます。静的プロキシと比較して、動的プロキシの利点は、各プロキシクラスの機能を変更せずに、プロキシクラスの関数を均一に簡単に処理できることです。これはより抽象的です。例を組み合わせて、動的プロキシの利点がどのように反映されるかを紹介しましょう。
ここで、デリゲートクラスでメソッドを実行する前に、「 "before" before "の出力を実装する必要があるとします。上記の例では、ベンダークラスをデリゲートクラスとして紹介し、BusinessAgentクラスをプロキシクラスとして紹介します。まず、静的プロキシを使用してこの要件を達成しましょう。関連するコードは次のとおりです。
パブリッククラスBusinessAgent Implements Sell {Private Vendor Mvendor; Public BusinessAgent(ベンダーベンダー){this.mvendor = vendor; } public void sell(){system.out.println( "before"); mvendor.sell(); system.out.println( "after"); } public void ad(){system.out.println( "before"); mvendor.ad(); system.out.println( "after"); }}上記のコードから、静的プロキシを通じてニーズを実装するには、各メソッドに対応するロジックを追加する必要があることを理解できます。ここには2つの方法しかないので、ワークロードは大きくありません。販売インターフェイスに数百の方法が含まれている場合はどうなりますか?現時点では、静的プロキシを使用すると、多くの冗長コードが記述されます。動的プロキシを使用することにより、各メソッドを1つずつ変更せずに、すべてのプロキシクラスのメソッドを均一に処理するために「均一な表示」を作成できます。ダイナミックプロキシを使用してニーズを実装する方法を紹介しましょう。
2。動的プロキシを使用します
(1)InvocationHandlerインターフェイスで動的プロキシを使用する場合、プロキシクラスとデリゲートクラスの間にある仲介クラスを定義する必要があります。この中間クラスは、InvocationHandlerインターフェイスを実装するために必要です。このインターフェイスの定義は次のとおりです。
public interface rivocationhandler {object invoke(object proxy、method method、object [] args); }名前のInvocationHandlerから、このインターフェイスを実装する調停クラスが「コールプロセッサ」として使用されていることがわかります。プロキシクラスオブジェクトのメソッドを呼び出すと、この「呼び出し」はInvokeメソッドに転送されます。プロキシクラスオブジェクトは、プロキシパラメーターとして渡されます。パラメーターメソッドは、プロキシクラスを呼び出す方法を識別します。 ARGSはこのメソッドのパラメーターです。このようにして、プロキシクラスのすべてのメソッドへの呼び出しは、呼び出すための呼び出しになるため、統合された処理ロジックをInvokeメソッドに追加できます(または、プロキシクラスの異なるメソッドをメソッドパラメーターに従って処理できます)。したがって、MediationクラスのInvokeメソッド実装に「前」に出力するだけで、DelegateクラスのInvokeメソッドを呼び出してから、「After」を出力する必要があります。段階的に実装しましょう。
(2)Delegateクラスの動的プロキシメソッドの下で、Delegateクラスは特定のインターフェイスを実装する必要があります。ここでは、Sell Interfaceを実装します。ベンダークラスの定義は次のとおりです。
パブリッククラスベンダーはsell {public void sell(){system.out.println( "in sell method"); } public void ad(){system、out.println( "ad method")}} (3)メディエーションクラス上記のように、メディエーションクラスは、コールプロセッサ「インターセプト」がプロキシクラスメソッドへの呼び出しとして、InvocationHandlerインターフェイスを実装する必要があります。仲介クラスの定義は次のとおりです。
パブリッククラスDynamicProxyは、InvocationHandlerを実装しています{private Object obj; // OBJはデリゲートクラスオブジェクトです。 public dynamicproxy(オブジェクトobj){this.obj = obj; } @Override public object invoke(Object Proxy、Method Method、Object [] args)Throws throwable {system.out.println( "before");オブジェクトresult = method.invoke(obj、args); system.out.println( "after");返品結果; }}上記のコードから、中間クラスにデリゲートオブジェクトの参照が保持されていることがわかります。また、デリゲートオブジェクトの対応するメソッドがInvokeメソッド(11行目)で呼び出されます。これを見たとき、おなじみのようだと思いますか?集約方法を介してデリゲートオブジェクト参照を保持し、最終的にすべての外部呼び出しを変換して、デリゲートオブジェクトへの呼び出しに呼び出します。これは上記で紹介した静的プロキシの実装方法ではありませんか?実際、仲介クラスとデリゲートクラスは静的プロキシ関係を形成します。この関係では、仲介クラスはプロキシクラスであり、代表クラスは代表団クラスです。プロキシクラスと中間クラスも静的プロキシ関係を形成します。この関係では、仲介クラスは委任クラスであり、プロキシクラスはプロキシクラスです。言い換えれば、動的プロキシ関係は、動的プロキシの原理である2つの静的プロキシ関係の2セットで構成されています。プロキシクラスを動的に生成する方法を紹介しましょう。
(4)ダイナミック生成プロキシクラスダイナミック生成プロキシクラス関連コードは次のとおりです。
public class main {public static void main(string [] args){//メディエーションクラスのインスタンスを作成しますdynamicproxy inter = new DynamicProxy(new Vendor()); //この文は$ proxy0.classファイルを生成します。これは動的に生成されたプロキシクラスファイルsystem.getProperties()。 //プロキシクラスインスタンスの販売販売販売=(販売)(proxy.newproxyinstance(sell.class.getClassLoader()、new class [] {sell.class}、inter)); //プロキシクラスオブジェクトを介してプロキシクラスメソッドを呼び出すと、実際にはsell.sell()を呼び出すためのInvokeメソッドに移動します。 sell.ad(); }}上記のコードでは、プロキシクラスのnewProxyInstanceメソッドを呼び出して、プロキシクラスインスタンスを取得します。このプロキシクラスは、指定したインターフェイスを実装し、指定された呼び出しプロセッサにメソッド呼び出しを配布します。この方法の宣言は次のとおりです。
コードを次のようにコピーします:public staticオブジェクトNewProxyInstance(classLoader Loader、class <?
メソッドの3つのパラメーターは次のとおりです。
ローダー:プロキシクラスのクラスロダーを定義します。
インターフェイス:プロキシクラスによって実装されたインターフェイスのリスト
H:プロセッサを呼び出します。つまり、InvocationHandlerインターフェイスを実装する上記で定義したクラスインスタンスは、動的プロキシが適切に機能するかどうかを確認してみましょう。ここで実行する出力は次のとおりです。
これは、私たちの動的プロキシが実際に機能していることを示しています。
上記の動的プロキシの原則について簡単に言及しました。ここで簡単に要約します。まず、newProxyInstanceメソッドを使用してプロキシクラスインスタンスを取得し、次にこのプロキシクラスインスタンスを使用してプロキシクラスメソッドを呼び出すことができます。プロキシクラスメソッドでは、実際に調停クラスのInvokeメソッド(プロセッサと呼ばれる)を呼び出します。 Invokeメソッドでは、デリゲートクラスの対応する方法を呼び出し、独自の処理ロジックを追加できます。
上記はこの記事のすべての内容です。みんなの学習に役立つことを願っています。誰もがwulin.comをもっとサポートすることを願っています。