java代理モードの解説


スタティックエージェントモード:
着信を簡単に受け取り、代理されるオブジェクトにアクセスする権限の設定を行います。
一般的なやり方は、プロキシクラスと同じ方法を実現し、方法において権限制御を行い、権限があるかどうかを判断することです。
例:
public interface SJSkill {

public void  ();

public void   ();

}

public class FBB implements SJSkill{

public void  (){

System.out.println("fbb  。。。");

}

public void   (){

System.out.println("fbb  。。。");

}

}

public class JJRStaticProxy implements SJSkill{



private FBB fbb = new FBB();



@Override

public void  () {

System.out.println("    :   ????");

fbb. ();

System.out.println("    :  ,        ");

}



@Override

public void   () {

System.out.println("    :   ????");

fbb.  ();

System.out.println("    :  ,        ");

}



}



public class StaticProxyTest {

@Test

public void test01(){

JJRStaticProxy jjr = new JJRStaticProxy();

jjr. ();

jjr.  ();

}

}
静的代理設計モードの利点:
構造がはっきりしていて分かりやすいです。
短所:
被代理人が複数の方法を持っている場合、代理人も複数の方法を開発する必要があり、その中にはしばしば大量の重複コードが存在し、コードの重複が存在する。
ダイナミックエージェント:
jdkはダイナミックエージェントを内蔵しています。
jdkでは、動的エージェントが実現するツールクラスを提供し、直接にこのツールクラスを使用すると、エージェントを作成することができ、内蔵されたリターン関数によって、エージェントが動作中である実行ロジックを指定することができ、jdk原生apiに基づく動的エージェントメカニズムが実現される。
java.lang.reflect
クラス
java.lang.Object
static Object
newProxyInstance(Class Loader) loader,Class>[] インターフェース、InvocationHandler h)          指定されたインターフェースのプロキシクラスの例を返します。このインターフェースは、方法を指定された呼び出し処理プログラムに割り当てることができます。
パラメータの説明:
Class Loader loader:ジェネレータクラスのキャリアを生成するために使用され、一般的には、エージェントクラスのキャリアに入ることができます。
interfaces:代理人が実現するインターフェースを生成することを要求します。一般的には、被代理人と同じインターフェースを実現し、被代理人と同じ方法を保証します。
 InvocationHandler:コールバック関数を設定するためのコールバックインターフェースは、ユーザーがこのインターフェースを実現するためのクラスを書く必要があります。コード処理代行者の呼び出し方法を作成する際のコールバックプロセスは、通常ここで本当のオブジェクトの方法を呼び出し、方法の前と後に追加の操作を行うことができます。
public class ProxyDemo {

@Test

public void ProxyTest(){        

Start F=(Start)Proxy.newProxyInstance(FBB.class.getClassLoader(), FBB.class.getInterfaces(), new InvocationHandler() {

@Override

public Object invoke(Object proxy, Method method, Object[] a) throws Throwable {

//     

System.out.println(proxy.getClass());

System.out.println(method.getName());



System.out.println(Arrays.toString(a));



Object invoke = method.invoke(new FBB(), a);

return invoke;

}

});

F.song(1);



}

}

interface Start{

void song(int x);

}

class FBB implements Start{

@Override

public void song(int x) {

System.out.println(x+"fbb  K");

}        

}
invokeパラメータ解析:
proxy:エージェント
method:現在呼び出されているメソッドオブジェクト
a:現在の引数配列
javaダイナミックエージェントの特徴:
利点:
静的なエージェントのように、プロキシ方法ではなく、コールバック関数で処理すればいいです。反復コードが減少します。
短所:
javaの動的エージェントは、代理人によって実現され、被代理人と同じインターフェースによって両者が同じ方法を持つことを保証するものであり、代理人によって代理されたい方法がインターフェースに属しないなら、生成された代理人は当然この方法を持つことができなくなり、この方法に対する代理を実現することができない。
要約:javaの動的エージェントメカニズムは、インターフェースに基づいて行われ、プロキシされる方法にインターフェースのサポートがあるかどうか。
Cglib実現の動的エージェント:
Cglibは、サードパーティが提供する動的エージェントの実現ツールであり、インターフェースの有無にかかわらず動的エージェントを実現することができる。
CGLOIBが動的エージェントを実現する原理は、生成された動的エージェントクラスは、エージェントクラスのサブクラスであるため、親と同じ方法を持っており、処理が実現される。
public class CglibDemo {



@Test

public void test1(){

//   

Enhancer en=new Enhancer();

//     --     

//en.setInterfaces();

//    --           ,       

en.setSuperclass(new FBB1().getClass());

//       --           ,              

//                ,                 

en.setCallback(new MethodInterceptor() {



@Override

public Object intercept(Object proxy, Method method, Object[] arg, MethodProxy mp) throws Throwable {

System.out.println(proxy.getClass());

System.out.println(method.getName());

System.out.println(Arrays.toString(arg));

System.out.println(mp.getSuperName());



return method.invoke(new FBB1(), arg);

}

});

FBB1 F=(FBB1)en.create();

F.song(1);

}

}

class FBB1{

public void song(int x) {

System.out.println(x+"fbb  K");

}        

}
CGLOIBダイナミックエージェントの特徴:
利点:インターフェースがあるかどうかに関わらず、ダイナミックエージェントが実現され、使用シーンは制限されない。
短所:第三者が提供する動的代理機構は、元のものではない。