動的エージェントの詳細()


前言
JAvaの動的エージェントメカニズムの出現により、javaプログラマーは自分でエージェントクラスを手動で実現する必要がない.jdkのエージェントクラスを使用して、エージェントクラスにインタフェースのセットとnewが本当に実行するオブジェクトを指定します.エージェントクラスは,すべてのメソッドに対する呼び出し割り当てを各具体的なオブジェクトに委任して反射実行し,割り当て依頼の過程で開発者は自分の状況に応じて依頼のオブジェクトや機能を調整することができ,非常に柔軟である.
 
プロキシプロキシ:デザインモードせっけいもーど
エージェント・モードは、オブジェクトの制御を制御するためにエージェントを提供する設計モードです.エージェントクラスは,委任クラスに対してメッセージを前処理し,メッセージを転送し,メッセージが委任されて実行された後の後続処理を行う.
一般的に動作の一貫性を保つために、エージェントクラスと委任クラスは通常同じインタフェースを実現するので、訪問者にとって両者には違いはありません.エージェントクラスへのアクセスにより、委任クラスへのアクセスを効果的に制御することができ、委任クラスオブジェクトをよく隠して保護するとともに、異なる制御ポリシーを実施するために柔軟性を確保することができます.JAvaダイナミックエージェントメカニズムはエージェントモデルをほぼ完璧に実践した.
 
関連するクラスとインタフェース
JAvaダイナミックエージェントに関連するクラスとインタフェース:
java.lang.reflect,Proxy:javaダイナミックエージェントメカニズムのプライマリクラスであり、インタフェースのダイナミックな生成エージェントクラスとそのオブジェクトのセットを生成するための静的メソッドのセットを提供します.
 
//  1:                    
static InvocationHandler getInvocationHandler(Object proxy);

//  2:                                   

static Class getProxyClass(ClassLoader loader , Class[] interfaces);

//  3:                      
static boolean  isProxyClass(Class cl);

//  4:            、                   

static Object  newProxyInstance(ClassLoader loader ,Class[] interface ,InvocationHandler h)

 
java .lang.reflect.invocationHandler:これは呼び出しプロセッサインタフェースで、動的エージェントクラスオブジェクト上のメソッド呼び出しを集中的に処理するためのinvocationメソッドをカスタマイズし、通常、このメソッドでは依頼クラスへのエージェントアクセスを実現します.
 
 
 
 
 
 
 
//                       。            ,              ,             。                               


Object  invoke(Object proxy , Method method ,Object[] args);

動的エージェントクラスが生成されるたびにオブジェクトを指定する必要があります(Proxy静的メソッドのメソッド4の最初のパラメータを参照).
 
java.lang.ClassLoader:クラスのローダです.負荷はクラスのバイトコードをjava仮想マシン(jvm)にロードし、オブジェクトを定義してから使用できます.Proxy静的方法で生成する動的エージェントクラスは、クラスローダによってロードする必要があり、通常のクラスとの唯一の違いは、jvmが実行時に動的に生成するバイトコードであり、予め存在するものではないことである.classファイルにあります.
動的プロキシクラスオブジェクトを生成するたびに、クラスローダオブジェクトを指定する必要があります(Proxy静的メソッド4の最初のパラメータを参照).
 
エージェントメカニズムとその特徴:
まずオオカミjavaダイナミックエージェントの使用方法について説明します.具体的な手順は次のとおりです.
 
1.InvocationHandlerインタフェースを実現することによって、独自の呼び出しプロセッサを作成する.
 
 
 
 
 
 
 
 
 
 
 
 
 
 
//InvocationHandlerImpl   InvocationHandler  ,                 
    ,                   ,               
 InvocationHandler  handler = new InvocationHandlerImpl(...);
//  Proxy   Interface                    
Class clazz =Proxy.getProxyClass(classLoader , new Class[]{Inteface.class});
//                   
Constructor constructor = clazz.getConstructor(new Class[]{InvocetionHandler.class});
//                  

Interface proxy  =(Interface)constructor.newInstance(new Object[]{handler});





 
Proxyの静的方法newProxyInstanceはすでにステップ2から4のプロセスをカプセル化しているので、簡略化された
 
 
//InvocationHandlerImpl    InvocationHandler  ,                   
InvocationHandler handler = new InvocationHandlerImpl(...);

 
動的エージェントクラスの特徴:
1、パケット:すべてのインタフェースがpublicである場合、それは最上位のパケット(すなわちパケットのパスが空)に定義され、すべてのエージェントのインタフェースにpublic以外のインタフェース(インタフェースはProtectまたはprivateとして定義できないので、他はパケットアクセスレベル)がある場合、インタフェースが存在するパケットに定義されます.このような理由は、エージェントクラスがパッケージの管理によって正常に定義され、アクセスできないことを最大限に保証するためである.
2、クラス修飾子:finalとpublic修飾子を有するクラス;すべてのクラスにアクセスできますが、継承できません.
3、クラス名:形式は$ProxyNで、ここでNは1つずつ増加するアラビア数字で、ProxyクラスがN回目に生成した動的代理クラスを表して、注意すべきは毎回Proxyメソッドを呼び出してすべてN+1をさせるのではありません
4、クラス継承関係:このクラスはProxyメソッドを継承し、すべてのエージェントのインタフェースを実現している.これも、エージェントクラスがエージェントのクラスのインタフェースに安全に変換できる理由である.
 
次に、エージェントクラスのいくつかのインスタンスの特徴を示します.
各インスタンスには呼び出しプロセッサオブジェクトが関連付けられており、Proxyが静的な方法getInvocationHandlerを提供することで、プロキシクラスインスタンスの呼び出しプロセッサオブジェクトを得ることができます.エージェントクラスインスタンスがそのエージェントインタフェースを使用するメソッドをアップグレードすると、これらのメソッドは最終的に呼び出しプロセッサのInvokeメソッドに割り当てられて実行されます...
 
エージェントインタフェースの一連のインタフェースの特徴:
まず、動的エージェントクラスコード生成時のコンパイルエラーを回避するために、重複するインタフェースがないことに注意してください.次に、これらのインタフェースはクラスローダに対して表示される必要があります.それ以外の場合、クラスローダはリンクできず、クラス定義に失敗します.再度、エージェントが必要なすべてのpublicインタフェースは同じパッケージにある必要があります.そうしないと、エージェントクラスも失敗します.最後に、インタフェースの数は65535を超えてはならない.これはjvm設定の制限である.
 
次に、例外の処理の特徴を示します.
プロセッサインタフェース宣言を呼び出す方法から、理論的には、すべての例外がThrowableインタフェースを実現しているため、任意のタイプの例外を放出することができることが明らかになった.事実上は否定的だ.なぜなら、子が親のインタフェースを実装したり、親を上書きしたりする方法では、放出された例外の範囲が親の範囲内である必要があります.
 
動的エージェントで本番エージェントクラスのコードを実装する方法は、ProxyGeneratorです.
 
 
JAvaのダイナミックエージェントの米国で不足している点は,Interfaceエージェントの束縛のみをサポートすることである.このデザインはこの残念さに決まっている.