ホームページ  >  記事  >  Java  >  Javaプロキシモードの概要

Javaプロキシモードの概要

王林
王林転載
2021-01-27 09:50:442898ブラウズ

Javaプロキシモードの概要

まず、エージェントとは何かを紹介します。

(学習ビデオ共有: java ビデオ チュートリアル)

プロキシは設計パターンであり、その中心的な考え方は、ターゲットへのアクセスをプロキシ オブジェクトに転送することです。この利点は、コードを変更せずに、ターゲット オブジェクトがプロキシ オブジェクトを通じていくつかの追加機能を追加できることです。これは、元のコードを変更せずに、エージェントを通じていくつかの拡張機能を追加するプログラミングのアイデアです。

プロキシの処理は図の通りで、ユーザーはプロキシオブジェクトにアクセスし、プロキシオブジェクトはターゲットオブジェクトにアクセスすることでユーザーがターゲットオブジェクトにアクセスするという目的を達成します。

##プロキシ パターンには、次の 3 つの役割が含まれています。 Javaプロキシモードの概要

ISubject: インターフェイス オブジェクト。オブジェクトとそのプロキシによって共有されるインターフェイスです。

TargetSubject: ターゲット オブジェクトは、抽象テーマ インターフェイスを実装するクラスです。

Proxy: プロキシ ロール。ターゲット オブジェクト TargetSubject への参照が含まれているため、実際のオブジェクトを操作できます。プロキシ オブジェクトはターゲット オブジェクトと同じインターフェイスを提供するため、いつでもターゲット オブジェクトを置き換えることができます。同時に、プロキシ オブジェクトは、ターゲット オブジェクトに対して操作を実行するときに他の操作を追加できます。これは、実際のオブジェクトをカプセル化するのと同じです。

一般的なプロキシ モードは静的プロキシと動的プロキシに分けられ、Java での動的プロキシの実装は JDK 動的プロキシと cglib プロキシに分けられます。

静的プロキシ

前述したように、プロキシ モードには 3 つの役割があります。1 つはターゲット インターフェイス、2 つ目はターゲット オブジェクト、3 つ目はプロキシ オブジェクトです。

次に、特定のコードで実装します。まず、ターゲット インターフェイスは次のとおりです:

 public interface IBlogService {

    void writeBlog();
}

ターゲット オブジェクトはターゲット インターフェイスを実装し、コードは次のとおりです:

public class BlogService implements IBlogService {

    @Override
    public void writeBlog() {
        System.out.println("i'm writing...");
    }
}

コンストラクター メソッドを使用した静的プロキシ オブジェクト ターゲット オブジェクトが取得され、ターゲット インターフェイスが実装されます。ターゲット オブジェクトのメソッドは、ターゲット インターフェイスのメソッドで呼び出されます。コードは次のとおりです:

public class BlogStaticProxy implements IBlogService{
    private IBlogService blogService;

    public BlogStaticProxy(IBlogService blogService) {
        this.blogService = blogService;
    }

    @Override
    public void writeBlog() {
        System.out.println("start writing...");
        blogService.writeBlog();
        System.out.println("end writing...");
    }
}

Staticプロキシ オブジェクトの場合、構築メソッドを通じてターゲット オブジェクトが取得され、目的が達成されます。インターフェイスの場合、ターゲット インターフェイスのメソッドでターゲット オブジェクトのメソッドが呼び出されます。コードは次のとおりです:

public class BlogStaticProxy implements IBlogService{
    private IBlogService blogService;

    public BlogStaticProxy(IBlogService blogService) {
        this.blogService = blogService;
    }

    @Override
    public void writeBlog() {
        System.out.println("start writing...");
        blogService.writeBlog();
        System.out.println("end writing...");
    }
}

Test :

public class TestStaticProxy {

    public static void main(String[] args) {
        IBlogService target = new BlogService();
        BlogStaticProxy proxy = new BlogStaticProxy(target);
        proxy.write();
    }
}
start writing…
i’m writing…
end writing…

静的プロキシ、ターゲット オブジェクトを変更せずに、追加の拡張機能を作成してプロキシ オブジェクトを渡すことができます。ただし、静的メソッドは柔軟性が低いため、ターゲット インターフェイスのコードを変更すると、ターゲット オブジェクトとプロキシ オブジェクトの両方を変更する必要があります。

動的プロキシは、この状況をある程度回避します。動的プロキシは、ターゲット インターフェイスを実装するためにプロキシ オブジェクトを必要とせず、Java 仮想マシンのメモリにプロキシ オブジェクトを動的に生成します。

Jdk 動的オブジェクト

Jdk の動的プロキシは、次の 3 つのパラメータを持つ Proxy クラスによって生成されます。

ClassLoader ローダー: クラス ローダーを使用する現在のターゲット オブジェクトと、その取得方法を指定します。ローダーは修正されています

Class>[] インターフェイス、: ターゲット オブジェクトによって実装されるインターフェイスのタイプ。ジェネリックを使用してタイプを確認します。

InvocationHandler h: イベント処理になります。ターゲット オブジェクトのメソッドが実行されるとトリガーされます。イベント ハンドラーのメソッドは、現在の実行ターゲット オブジェクトのメソッドをパラメータとして

 public static Object newProxyInstance(ClassLoader loader,
                                          Class<?>[] interfaces,
                                          InvocationHandler h)
        throws IllegalArgumentException
    {

    }

に渡します。Jdk の動的プロキシ コードは次のとおりです。
 public class JdkBlogProxyFactory {

    private Object target;

    public JdkBlogProxyFactory(Object target) {
        this.target = target;
    }

    public Object newInstance() {
        return Proxy.newProxyInstance(target.getClass().getClassLoader(), target.getClass().getInterfaces(),
                (proxy, method, args) -> {
                    System.out.println("start writing");
                    Object o = method.invoke(target, args);
                    System.out.println("end writing");
                    return o;
                });
    }
}

テスト クラス:

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

        IBlogService target = new BlogService();

        System.out.println(target.getClass());

        // 给目标对象,创建代理对象
        IBlogService proxy = (IBlogService) new JdkBlogProxyFactory(target).newInstance();
        // class $Proxy0   内存中动态生成的代理对象
        System.out.println(proxy.getClass());

        // 执行方法   【代理对象】
        proxy.writeBlog();
    }
}

Control 台湾の印刷物は次のとおりです:

class com.forezp.proxy.BlogService
class com.sun.proxy.$Proxy0
start writing
i&#39;m writing...
end writing

CGLib ダイナミック プロキシ

CGLib は、非常に低レベルのバイトコード テクノロジを使用します。バイトコード テクノロジを通じてクラスのサブクラスを作成し、それをサブクラスで使用することです。メソッド インターセプト テクノロジは、親クラスのメソッドへのすべての呼び出しをインターセプトし、それに応じて横断的なロジックを組み込むために使用されます。

CglibBlogFactory プロキシ ファクトリ クラスは次のとおりです:

public class CglibBlogFactory implements MethodInterceptor {

    private Object target;

    public CglibBlogFactory(Object target) {
        this.target = target;
    }

    //给目标对象创建一个代理对象
    public Object getProxyInstance() {
        //1.工具类
        Enhancer en = new Enhancer();
        //2.设置父类
        en.setSuperclass(target.getClass());
        //3.设置回调函数
        en.setCallback(this);
        //4.创建子类(代理对象)
        return en.create();
    }

    @Override
    public Object intercept(Object o, Method method, Object[] objects, MethodProxy methodProxy) throws Throwable {
        System.out.println("start writing...");
        //执行目标对象的方法
        Object returnValue = method.invoke(target, objects);
        System.out.println("end writing...");
        return returnValue;
    }
}

テスト クラス:

public class TestCglib {

    public static void main(String[] args) {
        IBlogService target = new BlogService();
        //代理对象
        IBlogService proxy = (IBlogService) new CglibBlogFactory(target).getProxyInstance();
        //执行代理对象的方法
        proxy.writeBlog();
    }
}

プログラムの実行、コンソール出力:

start writing...
i&#39;m writing...
end writing...

関連する推奨事項:

java 入門チュートリアル

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

声明:
この記事はjuejin.imで複製されています。侵害がある場合は、admin@php.cn までご連絡ください。
前の記事:Javadoc仕様の概要次の記事:Javadoc仕様の概要