Java プロキシとは何ですか?
プロキシとは何ですか? 実際、理解するのは簡単です。つまり、ターゲットに直接アクセスするのではなく、次のような中間層を通じてアクセスします:
Java の静的プロキシ
たとえば、Java コードで書かれたバナナやリンゴなどの果物の一部は、おそらく次のようになります: (推奨チュートリアル: java チュートリアル)
//Fruit.java/** * 水果的接口 */public interface Fruit { /** * 获取水果的名字 */ public String getName(); }//Apple.javapublic class Apple implements Fruit { @Override public String getName() { return "苹果"; } }//Banana.javapublic class Banana implements Fruit { @Override public String getName() { return "香蕉"; } }
果物を食べるには、皮をむかなければなりません。果物ごとにサブクラスを書くことはできません。皮をむくのはクラスが処理します。したがって、エージェントを作成し、食べる前にリンゴの皮をむくことができます。以下のように、元のフルーツを 1 つのレイヤーでラップします。
//PeelFruitProxy.java/** * 代理,让每个水果去皮 */public class PeelFruitProxy implements Fruit { private Fruit mFruit; public PeelFruit(Fruit fruit) { this.mFruit = fruit; } @Override public String getName() { System.out.println("proxt:" + proxy.getClass().getName()); return "去皮的" + mFruit.getName(); } }
テスト クラスを追加しました。テスト クラスは次のとおりです。
//Main.javapublic class Main { public static void main(String[] args) { Apple apple=new Apple();//原始的苹果 Banana banana=new Banana();//原始的香蕉 PeelFruitProxy peelApple=new PeelFruitProxy(apple);//代理,添加去皮功能 PeelFruitProxy peelBanana=new PeelFruitProxy(banana);//代理,添加去皮功能 System.out.println(peelApple.getName()); System.out.println(peelBanana.getName()); } }
上記は Java の静的プロキシです簡単に言うと、元のターゲット オブジェクトをレイヤーでラップし、新しいものを追加して、ターゲット自体を呼び出すことです。しかし、このような静的プロキシの場合、インターフェイスにはプロキシが必要になり、実装は非常に面倒ではないでしょうか?
Java の動的プロキシ
Java には、これを行う Proxy というクラスがあり、リフレクションとプロキシ インターセプトを直接使用できます。このクラスについて簡単に紹介します。実際、最も一般的に使用される静的メソッドは Proxt.newProxyInstance() で、次のようになります:
public static Object newProxyInstance(ClassLoader loader, Class<?>[] interfaces, InvocationHandler h)
まず、InvocationHandler を実装し、invoke メソッドを実装し、ターゲットを呼び出す必要があります。 object.time では、invoke メソッドが最初に呼び出され、実装者はこのメソッド内で呼び出し先メソッドを積極的に呼び出す必要があります。
//FruitInvocationHandler.java/** * 调用方法拦截器 */public class FruitInvocationHandler implements InvocationHandler { private Fruit mFruit; public FruitInvocationHandler(Fruit fruit) { this.mFruit = fruit; } @Override public Object invoke(Object proxy, Method method, Object[] args) throws Throwable { String result = (String) method.invoke(mFruit, args);//需要在这个方法里面,主动调用被代理的对象。 return "去皮的" + result; } }
実行します:
//Main.Javapublic class Main { public static void main(String[] args) { Apple apple = new Apple(); Fruit proxyApple = (Fruit) Proxy.newProxyInstance(Fruit.class.getClassLoader(), new Class[]{Fruit.class}, new FruitInvocationHandler(apple)); System.out.println(proxyApple.getClass().getName()); System.out.println(proxyApple.getName()); Banana banana = new Banana(); Fruit proxyBanana = (Fruit) Proxy.newProxyInstance(Fruit.class.getClassLoader(), new Class[]{Fruit.class}, new FruitInvocationHandler(banana)); System.out.println(proxyApple.getClass().getName()); System.out.println(proxyBanana.getName()); } }
このメソッドは、上記のように PeelFruitProxy を生成します (もちろん、表示される名前は com.sun です)。 proxy.$Proxy0) は、毎回記述する必要がないように動的に生成されます。実行時に任意のクラスをプロキシできるため、これが動的プロキシと呼ばれる理由でもあります。多くのプログラムの AOP はこの方法で実装されていますが、newProxyInstance() の 2 番目のパラメータはインターフェイスのリストですが、なぜこのリストがあるのでしょうか?
動的に生成されたプロキシ クラスも、簡単に下方に変換してそのメソッドを使用できるように、インターフェイスを実装する必要があるためです。そうしないと、生成されたクラスのクラス名は com.sun.proxy.$ になります。 Proxy0. がメモリ内にあるため、生成されたメソッドを呼び出すことができません。 ** したがって、この動的プロキシ メソッドには致命的な欠点があります。それは、プロキシされたクラスがインターフェイスを実装する必要があるということです。 **
CGLib プロキシ
cglib is a powerful, high performance and quality Code Generation Library, It is used to extend JAVA classes and implements interfaces at runtime.
もう 1 つのよく知られた Java プロキシ実装は、ASM に基づくコード生成フレームワークである CGLib (コード生成ライブラリ) です。これを使用できます。クラスを動的に生成してからメソッドのインターセプトを実装すると、ターゲット クラスがインターフェイスを実装する必要があるという JDK の動的プロキシの問題を回避できます。つまり、CGLib を使用して、上記の PeelFruitProxy を生成できます。
使い方を簡単にご紹介します まず、この CGLib はサードパーティのライブラリですので、それに依存する必要があります:
compile 'cglib:cglib:3.2.8 '
最新バージョンはここで見ることができます (新バージョン) [https://github.com/cglib/cglib/releases] それでは、試してみましょう。上記のエージェントを実装しましょう
//FruitMethodInterceptor.java/** * CGLib代理的方法拦截器 */public class FruitMethodInterceptor implements MethodInterceptor{ @Override public Object intercept(Object obj, Method method, Object[] args, MethodProxy proxy) throws Throwable { String result = (String) proxy.invokeSuper(obj, args);//主要,这里调用的是父类,也就是说, 生成的类和原始类是继承关系 return "去皮的"+result; } }//Main.javapublic class Main { public static void main(String[] args) { Enhancer enhancer = new Enhancer(); enhancer.setSuperclass(Apple.class); enhancer.setCallback(new FruitMethodInterceptor()); Apple apple = (Apple) enhancer.create(); System.out.println(apple.getClass().getName()); System.out.println(apple.getName()); } }
実行 結果は次のとおりです:
#同じ関数が実装されていることがわかりますが、Apple は元の Apple クラスではなくなりました。 com.zjiecode.learn.java. proxy.Apple$$EnhancerByCGLIB$$44ade224, はい、オリジナルの Apple ではなく、実際にこのクラスを使用しています。このクラスは Apple から継承し、最終的に Apple クラスのプロキシを実装します。このように、継承が使用されるため、プロキシされたクラスがインターフェイスを実装する必要はありません。もちろん、インターフェイスを介してエージェントを実装することもできます。
概要
最初のタイプのプロキシについてはここでは説明しませんが、単一のインターフェイス プロキシにのみ適しており、コンパイル時に決定されます。
2 番目と 3 番目のタイプのプロキシはすべて動的プロキシですが、次のような違いがあります:
1) JDK の動的プロキシはインターフェイス プロキシのみを実装でき、パッケージ化されたプロキシです。つまり、プロキシ プロセス中には、プロキシ オブジェクトとターゲット オブジェクトの 2 つのオブジェクトが存在し、ターゲット オブジェクトはプロキシ オブジェクトにパッケージ化されます。
2) CGLib のプロキシは、ターゲット オブジェクトを継承し、新しいクラスを生成し、プロキシを実装します。このように、メモリ内にプロキシ オブジェクトがあり、ターゲット オブジェクトはありません。直接継承が使用されます。メソッド
プロキシ クラスの生成は実行時に行われ、コンパイル時にクラスを生成する Javapoet とは異なります。
以上がJavaプロキシとは何ですかの詳細内容です。詳細については、PHP 中国語 Web サイトの他の関連記事を参照してください。

この記事では、さまざまなJava Garbage Collectionアルゴリズム(シリアル、パラレル、CMS、G1、ZGC)、そのパフォーマンスへの影響、および大きなヒープを持つアプリケーションの適合性について説明します。

この記事では、Java Virtual Machine(JVM)について説明し、さまざまなプラットフォームでJavaプログラムを実行する際の役割について詳しく説明しています。 JVMの内部プロセス、主要コンポーネント、メモリ管理、ガベージコレクション、およびパフォーマンスの最適化について説明します

Javaのナショーンエンジンは、Javaアプリ内でJavaScriptスクリプトを可能にします。重要な手順には、ナショーンのセットアップ、スクリプトの管理、パフォーマンスの最適化が含まれます。主な問題には、ナショーンのdeprecによるセキュリティ、記憶管理、将来の互換性が含まれます

Javaのリソースでの試行は、ファイルストリームやデータベース接続などのリソースを自動的に閉じることでリソース管理を簡素化し、コードの読みやすさと保守性を向上させます。

Java Enumsは、固定された値のセットを表し、カスタムメソッドとコンストラクターを介してタイプの安全性、読みやすさ、および追加の機能を提供します。それらはコード組織を強化し、効率的なバリューハンドリングのためにスイッチステートメントで使用できます。


ホットAIツール

Undresser.AI Undress
リアルなヌード写真を作成する AI 搭載アプリ

AI Clothes Remover
写真から衣服を削除するオンライン AI ツール。

Undress AI Tool
脱衣画像を無料で

Clothoff.io
AI衣類リムーバー

AI Hentai Generator
AIヘンタイを無料で生成します。

人気の記事

ホットツール

ZendStudio 13.5.1 Mac
強力な PHP 統合開発環境

SublimeText3 Linux 新バージョン
SublimeText3 Linux 最新バージョン

VSCode Windows 64 ビットのダウンロード
Microsoft によって発売された無料で強力な IDE エディター

SublimeText3 Mac版
神レベルのコード編集ソフト(SublimeText3)

ドリームウィーバー CS6
ビジュアル Web 開発ツール
