Javaにおけるプロキシパターンの実装

プロキシパターンの概要

プロキシパターンはオブジェクトへのアクセスを制御する設計手法です。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

実装方式の比較

特性 静的プロキシ 動的プロキシ
実装タイミング コンパイル時 実行時
コード量 プロキシクラスが必要 ハンドラのみで実装
柔軟性 限定される 高い
パフォーマンス 直接呼び出し リフレクション利用

タグ: Java proxy DesignPattern StaticProxy DynamicProxy

7月26日 21:23 投稿