ホームページ  >  記事  >  Java  >  Java プロキシ パターンのサンプル コード分析

Java プロキシ パターンのサンプル コード分析

WBOY
WBOY転載
2023-04-18 16:52:07789ブラウズ

1. 動的プロキシ モード

動的プロキシの特徴:

  • オブジェクトをプロキシする場合、インターフェイスを実装する必要はありません

  • プロキシ オブジェクトの生成では、JDK の API を使用してメモリ内にプロキシ オブジェクトを動的に構築します (プロキシ オブジェクト/ターゲット オブジェクトを作成するインターフェイスのタイプを指定する必要があります)

## ダイナミック プロキシのエイリアス: JDK プロキシ、インターフェイス プロキシ

2、JDK ダイナミック プロキシ

クラス図:

Java プロキシ パターンのサンプル コード分析

Java ダイナミック プロキシ クラスは、java.lang.reflect パッケージの下の

にあり、通常、次の 2 つのクラスが含まれます:

1. インターフェイス InvocationHandler: このインターフェイスは、パブリック オブジェクト invoke(Object) メソッドを 1 つだけ定義します。 obj,Method メソッド , Object[] args) 実際の使用では、通常、最初のパラメータ obj はプロキシ クラスを指し、method はプロキシ メソッド、args はメソッドのパラメータ配列です。この抽象メソッドはプロキシ クラスに動的に実装されます。

2. プロキシ: このクラスは動的プロキシ クラスです

static Object newProxyInstance(ClassLoader loader, Class[] interfaces,InvocationHandler h):

プロキシ クラスのインスタンスを返します。返されたプロキシ クラスはプロキシ クラスとして使用できます (プロキシ クラスのインスタンスを使用できます)インターフェイスで宣言されたメソッド)

動的生成の実装手順:

  • インターフェイス InvocationHandler を実装するクラスを作成します。これは、呼び出しメソッドを実装する必要があります

  • プロキシ クラスとインターフェイスの作成

  • Proxy の静的メソッドを呼び出してプロキシ クラスを作成します:

    newProxyInstance(ClassLoaderloader,Class[]##)

  • #プロキシを介したメソッドの呼び出し
  • 3. JDK 動的プロキシ コードのデモ

たとえば、今は車があります。運転方法 :

public interface Moveable {
    void move();
}

今、車があります:

//实现Moveable 接口,并随机暂停一段时间

import java.util.Random;
public class Car implements Moveable{
    @Override
    public void move() {
        try{
            Thread.sleep(new Random().nextInt(1000));
            System.out.println("汽车行驶中");
        } catch (InterruptedException e) {
            e.printStackTrace();
        }
    }
}

タイム エージェント クラス:

import java.lang.reflect.InvocationHandler;
import java.lang.reflect.Method;

public class TimeHandler implements InvocationHandler{

    public TimeHandler(Object target){
        super();
        this.target = target;
    }
    private Object target;


    /**
     *
     * @param proxy :被代理的对象
     * @param method:被代理对象的方法
     * @param args:方法的参数
     * @return
     * @throws Throwable
     * 返回值:Object 方法的返回值
     */
    @Override
    public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {
        long startTime = System.currentTimeMillis();
        System.out.println("汽车开始行使");

        method.invoke(target);

        long endTime = System.currentTimeMillis();
        System.out.println("汽车行驶结束,行驶的时间为:"+(endTime-startTime)+"毫秒");
        return null;
    }
}

テスト クラス:

import java.lang.reflect.InvocationHandler;
import java.lang.reflect.Proxy;

public class Test {
    public static void main(String[] args) {

        Car car = new Car();
        InvocationHandler h = new TimeHandler(car);
        Class<?> cls = car.getClass();

        /**
         * newProxyInstanced的参数
         * 分别是:类加载器、实现的接口、实现的处理器
         */
        Moveable m = (Moveable) Proxy.newProxyInstance(cls.getClassLoader(),
                cls.getInterfaces(),h);
        m.move();
    }
}

出力結果は次のとおりです:

車は運転を開始します
車は運転中です

車は運転を終了します、運転時間は: 137 ミリ秒です
//次の時間はランダムに生成され、毎回異なります

注:

JDK プロキシは、インターフェイスを実装するクラスのみをプロキシできます。インターフェイスを実装していないクラスはプロキシできません。 cglib はクラス用です プロキシを実装するには、cglib の原理は、指定されたターゲット クラスのサブクラスを生成し、メソッドをオーバーライドして拡張を実現することですが、継承が使用されるため、最終的に変更されたクラスをプロキシにすることはできません。まだ完全にマスターしていない部分があるので、ここでは詳しく説明しません。他のブロガーの技術記事を参照してください。

以上がJava プロキシ パターンのサンプル コード分析の詳細内容です。詳細については、PHP 中国語 Web サイトの他の関連記事を参照してください。

声明:
この記事はyisu.comで複製されています。侵害がある場合は、admin@php.cn までご連絡ください。