まず、動的プロキシ モデルにおける 3 つの役割を分析します。
1. 抽象的な役割: 静的プロキシでは抽象クラスにすることができますが、動的プロキシではインターフェイスのみにすることができます
2. 実際のロール: 抽象ロールのメソッドを実装するだけです。
3. エージェントの役割: 最も嫌なことは、動的エージェントでのエージェントの役割です。実際のキャラクターへの参照を保持する必要があります。
これには、インターフェイスとクラス、InvocationHandler インターフェイスと Proxy クラスが含まれます。 JDK ドキュメントによると、InvocationHandler インターフェイスはクラスによって実装され、このクラスのインスタンスはプロキシ オブジェクトに対応するハンドラー オブジェクトです。プロキシ オブジェクトのメソッドが呼び出されると、そのメソッドはエンコードされ、対応するハンドラー オブジェクトの呼び出しメソッドに割り当てられて呼び出されます。
次のようにコードをコピーします。
// 抽象的な役割:
パブリック インターフェイス AbstractRole
{
public void show();
}
//実際のキャラクター:
パブリック クラス RealRole は AbstractRole を実装します
{
@オーバーライド
public void show(){ System.out.println("あなたの家を見せてください");
}
//エージェントの役割:
//これは単なる疑似エージェントだと思います。疑似エージェントは私が考えつきました = =! 、実際にはエージェントに対応するハンドラーであるため、
パブリック クラス ハンドラーは InvocationHandler を実装します。
{
private Object realRole; // プロキシ ロールは、オブジェクト タイプとして定義されている場合、ユニバーサルです。
public Handler(オブジェクト realRole)
{ this.realRole = realRole }
@オーバーライド
public Object invoke(オブジェクトプロキシ、メソッドメソッド、Object[] args)
{
System.out.println("Give me your Money"); // これはエージェント ロール自体によって追加される追加機能です。
Method.invoke(this.realRole, args); // リフレクションを通じて実際のロールのメソッドを呼び出します
System.out.println("Ok...house is yours");//これは、エージェント ロール自体によって追加される追加機能です。
}
public Object Factory()//ファクトリ メソッドを通じて実際のエージェント ロールを生成します
{
return Proxy.newProxyInstance(this.getClass().getClassLoader(), this.realObject.getClass().getInterfaces(), this); //プロキシの newProxyInstance メソッドには 2 つの非常に重要な機能があります。 1 つ目は、出力が $Proxy0 という名前のクラスである場合に、プロキシ クラスを動的に作成することです。2 つ目は、動的に作成されたクラスを通じてインスタンスを生成することです。
}
}
//クライアント:
パブリッククラステスト
{
public static void main(String[] args)
{
RealRole realRole = new RealRole();//どの実際のロールを表現するか、新しい実際のロールを作成するだけです
Handler handler = new Handler(realRole);//プロキシ クラスに対応するハンドラーもここで生成されます。これを疑似プロキシ オブジェクトと呼びます。
AbstractRole proxy = (AbstractRole)handler.factory();//ファクトリ メソッドを通じてプロキシ オブジェクトを生成します
}
}
ここでのエージェントの役割をどのようにして強制的に抽象役割に変換できるのか疑問に思われるかもしれません。その理由は、newProxyInstance メソッドにあります。前述したように、このメソッドはクラスを自動的に生成し、そのクラスを通じてプロキシ オブジェクトを生成します。実際、このクラスは抽象ロール クラスを実装しています。 2 番目のパラメータで、実装するインターフェイスがすでに指定されているためです。したがって、強制的に転送した後、抽象ロールのメソッドを呼び出すことができます。
proxy.show();//わかりました!冒頭の赤字で示した「このメソッドはエンコードされ、対応するハンドラー オブジェクトの呼び出しメソッドに割り当てられます。」という文に注目してください。この文のため、show メソッドは次のようになります。もちろん、show メソッドのパラメータも引き継がれますが、ここでの show メソッドにはパラメータがありません。したがって、文 proxy.show() は実際にハンドラー オブジェクトの invoke メソッドを呼び出します。