プロキシパターンの概要
プロキシパターンはオブジェクトへのアクセスを制御する設計手法です。Javaでは主に静的なプロキシと動的なプロキシに分類され、それぞれ異なる実装方法と適用場面を持ちます。
静的プロキシの実装
静的なプロキシでは、インタフェースと実装クラスを定義し、明示的にプロキシクラスを作成します。
基本構成
public interface DataProcessor {
int execute(String input);
}
public class DataServiceImpl implements DataProcessor {
@Override
public int execute(String input) {
int result = 100;
System.out.println("Result=" + result + "; Input=" + input);
return result;
}
}
public class DataServiceProxy implements DataProcessor {
private final DataProcessor delegate;
public DataServiceProxy(DataProcessor delegate) {
this.delegate = delegate;
}
@Override
public int execute(String input) {
System.out.println("処理前のログ");
int output = delegate.execute(input);
System.out.println("処理後のログ");
return output;
}
}
使用方法
public class Client {
public static void main(String[] args) {
DataProcessor service = new DataServiceImpl();
DataProcessor proxy = new DataServiceProxy(service);
proxy.execute("サンプルデータ");
}
}
実行結果:
処理前のログ Result=100; Input=サンプルデータ 処理後のログ
動的プロキシの実装
JDKの動的プロキシ機能を使用すると、実行時にプロキシクラスを生成できます。
public class DynamicHandler implements InvocationHandler {
private final Object target;
public DynamicHandler(Object target) {
this.target = target;
}
@Override
public Object invoke(Object proxy, Method method, Object[] params) throws Throwable {
System.out.println("メソッド実行前: " + method.getName());
Object result = method.invoke(target, params);
System.out.println("メソッド実行後: " + method.getName());
return result;
}
}
public class ClientApp {
public static void main(String[] args) {
DataProcessor service = new DataServiceImpl();
DataProcessor dynamicProxy = (DataProcessor) Proxy.newProxyInstance(
DataProcessor.class.getClassLoader(),
new Class[]{DataProcessor.class},
new DynamicHandler(service)
);
dynamicProxy.execute("動的プロキシ");
}
}
実行結果:
メソッド実行前: execute Result=100; Input=動的プロキシ メソッド実行後: execute
実装方式の比較
| 特性 | 静的プロキシ | 動的プロキシ |
|---|---|---|
| 実装タイミング | コンパイル時 | 実行時 |
| コード量 | プロキシクラスが必要 | ハンドラのみで実装 |
| 柔軟性 | 限定される | 高い |
| パフォーマンス | 直接呼び出し | リフレクション利用 |