エージェントモード:
プロキシは基本的なデザインパターンの1つであり、追加または異なる操作を提供し、挿入されたオブジェクトは「実際の」オブジェクトのプロキシに使用されます。これらの操作は通常「実際の」オブジェクトとの通信を伴うため、プロキシは通常、仲介者の役割。
動的プロキシ
動的プロキシーは、実装フェーズでプロキシー・クラスを考慮する必要はありませんが、ランタイム・フェーズでどのオブジェクトを指定するか
動的プロキシーの利点:
- 明確な責任
実際の役割は、実際のビジネスロジックを実現することです。他の責任のないトランザクションを気にする必要はありません。後のエージェントを通じてトランザクションを完了することができます。付随的な結果は、単純で明確なプログラミングです。 - プロキシオブジェクトは、クライアントとターゲットオブジェクトの間の仲介者として機能できます。これは、仲介者として機能し、ターゲットオブジェクトを保護します。つまり、ターゲットオブジェクトを変更せずに機能を拡張できます。
- 高いスケーラビリティ。必要なメソッドに必要な機能を追加できます。
jdkに基づく動的プロキシを実装します。
Java.lang.reflect.ProxyはjdkのAPIで提供されています。動的プロキシの作成を完了するのに役立ちます。
注:動的プロキシオブジェクトの作成を完了するためにJavaでProxyを使用すると、インターフェースを実装するクラスのプロキシオブジェクトしか作成できません。
動的プロキシは、メモリ内に直接プロキシオブジェクトを生成することです。
引き続きAPIを見てください。
通常、このメソッドを使用してプロキシオブジェクトを作成します。これには3つのパラメータが必要です。
- ClassLoaderローダー:
変換は次のとおりです。各Classオブジェクトには、それを定義するClassLoaderへの参照が含まれています。配列クラスのクラスオブジェクトは、クラスローダーでは作成されませんが、Javaランタイムのニーズに応じて自動的に作成されます。Class.getClassLoader()によって返される配列クラスのクラスローダーは、その要素タイプのクラスローダーと同じです。要素タイプが基本タイプの場合、配列クラスにはクラスローダーがありません。したがって、プロキシする必要のあるオブジェクトが配列でない限り、ClassオブジェクトのgetClassLoader()を使用してClassLoaderオブジェクトを取得できます。
- Class <?> []インターフェース:
このメソッドはクラスクラスにあり、直接取得できます。このクラスは、ターゲットオブジェクトによって実装されるインターフェースを表します
- InvocationHandler h:
クリックすると、これがインターフェースであり、実装されていないinvoke(…)メソッドがあります。
つまり、ここに渡す必要があるオブジェクトは、このインターフェースを実装する必要があり、invoke()メソッドは、以下で説明するように完了する必要があります。このメソッドの3つのパラメーター:
-
パラメータ1:オブジェクトプロキシ、これはプロキシするオブジェクトです
-
パラメータ2:メソッドメソッド:アクセスする必要があるターゲット動作、つまり呼び出す必要があるメソッド
-
パラメーター3:オブジェクト[]引数:動作を呼び出すときに必要なパラメーター
このメソッドの主な機能は、プロキシオブジェクトを通じてビヘイビアーを呼び出すときに、ターゲットビヘイビアーを呼び出すことができるかどうかを制御することです。
以下はコードで実装されています:
//接口
public interface IUserService {
public String addUser(String username,String password);
}
//实现类
public class UserServiceImpl implements IUserService {
@Override
public String addUser(String username, String password) {
System.out.println("添加用户:" + username + " " + password);
return "hello " + username;
}
}
次に、UserServiceImplをプロキシするプロキシクラスを記述する必要があります。
public class UserServiceProxy implements InvocationHandler {
// 目标对象
private Object target;
public UserServiceProxy(Object target) {
this.target = target;
}
// 作用:创建代理对象
public Object createProxy() {
ClassLoader loader = target.getClass().getClassLoader();
Class[] interfaces = target.getClass().getInterfaces();
return Proxy.newProxyInstance(loader, interfaces, this);
}
@Override
public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {
System.out.println(method);
System.out.println(Arrays.asList (args));
System.out.println("方法调用之前");
Object result = method.invoke (target,args);
System.out.println("方法调用之后");
return result;
}
}
次にテストクラスを書きます:
public class Test {
public static void main(String[] args) {
//需要代理的对象
IUserService userservice = new UserServiceImpl ();
//创建代理类
UserServiceProxy up = new UserServiceProxy(userservice);
IUserService proxy = (IUserService) up.createProxy ();
//使用代理类进行方法增强
String s = proxy.addUser ("tom", "123");
System.out.println("s: " + s);
}
}
出力結果:
出力は以下で分析されます。
最初の出力はIUserService.addUserを指すメソッドオブジェクトで、2番目はinvoke()の3番目のパラメーターです。これは、実際にはプロキシオブジェクトを使用するときに使用するパラメーターです(通常、最初のパラメーターは使用されません)、次にaddUser()メソッドの前後にカスタムコンテンツを追加し、メソッド呼び出しの戻り値も取得しました。
要約:
- 動的プロキシーは、実装フェーズでプロキシー・クラスを考慮する必要はないが、ランタイム・フェーズでどのオブジェクトを指定するかを示すプロキシー・メソッドです。
- jdkの動的プロキシメソッドは、Proxy.newProxyInstance(ClassLoaderローダー、クラス<?> []インターフェイス、InvocationHandler h)メソッドを使用してプロキシオブジェクトを生成することです。エージェントクラスはメソッドの拡張を実行します。
- 開発では、動的プロキシを使用して、パフォーマンスの監視、権限の制御、ロギングなどの操作を完了します。SpringのAOPは、jdk動的プロキシを使用して部分的に実装されています。