私は、我々は、動的なエージェントモデルには見知らぬ人ではないと信じて、ビジネスコードはほとんど関与していない場合でも、春のAopカット指向プログラミングは、プロキシモデル+リフレクションメカニズムの使用は、誰もが非常に明確なはずです!
では、駆け出しの頃にこのような疑問を持つことはありますか?
1. 生成されたプロキシ・クラスはどこにあり、どのように見えますか?
2、なぜ対象クラスはそのインターフェイスを実装しなければならないのですか?
3.InvocationHandlerインターフェイスを実装したinvokeメソッドはいつ実行されますか?
質問への回答の冒頭では、コードのjdkサンプル版に基づいて動的なプロキシを参照してください。ここでは2つのポイントですが、1つはInvocationHandlerインターフェイスの実装では、2つのメソッドを呼び出すProxy.newProxyInstance()メソッドを介してプロキシオブジェクトに返すことです。
package com.my.test.design.proxy;
import java.lang.reflect.InvocationHandler;
import java.lang.reflect.Method;
import java.lang.reflect.Proxy;
public class MyProxy implements InvocationHandler {
 // プロキシされたオブジェクト
 private Object obj;
 // プロキシ・オブジェクトを返す
 public Object bind (Object obj){
 this.obj = obj;
 // 質問2:この返されたプロキシ・オブジェクトはどこにあり、どのように見えるか?
 return Proxy.newProxyInstance(obj.getClass().getClassLoader(),
 obj.getClass().getInterfaces(),this);
 }
 // 質問2:このinvokeメソッドはいつ実行されるのか?
 @Override
 public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {
 System.out.println("begin メソッドの実行を開始する");
 Object object = method.invoke(obj,args);
 System.out.println("end 実行メソッドの終了");
 return object;
 }
} 
静的プロキシを覚えて、静的プロキシは、プロキシクラスとターゲットクラスは、同じインターフェイスを実装する必要がありますし、プロキシされているオブジェクトを紹介するプロキシクラスでは、ターゲットクラスにアクセスできるように、最初のプロキシクラスを介してプロキシクラスにアクセスし、ターゲットクラスにアクセスするために行くので、ターゲットクラスへのアクセスの制御を達成するため
実際には、動的プロキシ-クラスは、プロキシオブジェクトを作成する詳細jdkが行うのに役立つことを除いて、同じです。それだけでなく、動的プロキシの最大の利点は、プロキシするクラスを事前に知っているわけではありませんが、決定で渡すオブジェクトに基づいているということです。
このパラメータを main メソッドに追加すると、ローカル・プロキシ・オブジェクト・クラス・ファイル $Proxy0.class が生成されます。
System.getProperties().put("sun.misc.ProxyGenerator.saveGeneratedFiles", "true");
生成されたファイルは、プロジェクト内のcomsun Proxyの下にあります。
以下は、$Proxy0.classファイルを逆コンパイルした結果です。
質問1:プロキシ・クラスはどこにあり、どのようなものですか?それがわかったところで
import java.lang.reflect.InvocationHandler;
import java.lang.reflect.Method;
import java.lang.reflect.Proxy;
import java.lang.reflect.UndeclaredThrowableException;
質問2:なぜターゲット・クラスはインタフェースを実装しているのか?デコンパイル後、プロキシ・クラスが見つかる$Proxy0はProxyクラスを継承しているからだ。
単一継承なので、インターフェイスを実装する必要がある。
public final class $Proxy0
 extends Proxy
 implements IBook
{
 private static Method m1;
 private static Method m3;
 private static Method m2;
 private static Method m4;
 private static Method m0;
 
 public $Proxy0(InvocationHandler paramInvocationHandler)
 {
 // MyProxyはInvocationHandlerインタフェースを実装している。
 super(paramInvocationHandler);
 }
 
 public final boolean equals(Object paramObject)
 {
 try
 {
 return ((Boolean)this.h.invoke(this, m1, new Object[] { paramObject })).booleanValue();
 }
 catch (Error|RuntimeException localError)
 {
 throw localError;
 }
 catch (Throwable localThrowable)
 {
 throw new UndeclaredThrowableException(localThrowable);
 }
 }
 質問3:プロキシ・クラスに実装されているインターフェースのinvokeメソッドはいつ実行されるか?
 saleBookメソッドを呼び出すと、invokeメソッドが実行される。
 public final void saleBook()
 {
 try
 {
 // this.hが親クラスのProxy InvocationHandlerのインスタンスであることはわかったが、サブクラスの本質は、$Proxy0.classに渡されたコンストラクタ・メソッドを通して、まだ彼ら自身のビジネス・クラスである。
 // そして、invokeメソッドはメソッドの実装である。,
 // m3 後ろのm3 = Class.forName("proxy.IBook").getMethod("saleBook", new Class[0]);
 // メソッド内の本当のプロキシ・オブジェクトは
 // まとめると、InvocationHandlerインターフェースのinvokeメソッドの実装は以下のようになる。
 this.h.invoke(this, m3, null);
 return;
 }
 catch (Error|RuntimeException localError)
 {
 throw localError;
 }
 catch (Throwable localThrowable)
 {
 throw new UndeclaredThrowableException(localThrowable);
 }
 }
 
 public final String toString()
 {
 try
 {
 return (String)this.h.invoke(this, m2, null);
 }
 catch (Error|RuntimeException localError)
 {
 throw localError;
 }
 catch (Throwable localThrowable)
 {
 throw new UndeclaredThrowableException(localThrowable);
 }
 }
 
 public final void buyBook()
 {
 try
 {
 this.h.invoke(this, m4, null);
 return;
 }
 catch (Error|RuntimeException localError)
 {
 throw localError;
 }
 catch (Throwable localThrowable)
 {
 throw new UndeclaredThrowableException(localThrowable);
 }
 }
 
 public final int hashCode()
 {
 try
 {
 return ((Integer)this.h.invoke(this, m0, null)).intValue();
 }
 catch (Error|RuntimeException localError)
 {
 throw localError;
 }
 catch (Throwable localThrowable)
 {
 throw new UndeclaredThrowableException(localThrowable);
 }
 }
 
 static
 {
 try
 {
 m1 = Class.forName("java.lang.Object").getMethod("equals", new Class[] { Class.forName("java.lang.Object") });
 m3 = Class.forName("proxy.IBook").getMethod("saleBook", new Class[0]);
 m2 = Class.forName("java.lang.Object").getMethod("toString", new Class[0]);
 m4 = Class.forName("proxy.IBook").getMethod("buyBook", new Class[0]);
 m0 = Class.forName("java.lang.Object").getMethod("hashCode", new Class[0]);
 return;
 }
 catch (NoSuchMethodException localNoSuchMethodException)
 {
 throw new NoSuchMethodError(localNoSuchMethodException.getMessage());
 }
 catch (ClassNotFoundException localClassNotFoundException)
 {
 throw new NoClassDefFoundError(localClassNotFoundException.getMessage());
 }
 }
}
// this.hこのhは、親クラスProxy /のInvocationHandlerインスタンスである。**
 * Constructs a new {@code Proxy} instance from a subclass
 * (typically, a dynamic proxy class) with the specified value
 * for its invocation handler.
 *
 * @param h the invocation handler for this proxy instance
 *
 * @throws NullPointerException if the given invocation handler, {@code h},
 * is {@code null}.
 */
 protected Proxy(InvocationHandler h) {
 Objects.requireNonNull(h);
 this.h = h;
 }





