Java の動的プロキシとリフレクション メカニズムの詳細な紹介 (コード例)

不言
リリース: 2019-01-24 11:03:13
転載
5512 人が閲覧しました

この記事では、Java の動的プロキシとリフレクションのメカニズムについて詳しく説明します (コード例)。必要な方は参考にしていただければ幸いです。

リフレクション メカニズム

Java 言語によって提供される基本的な機能。リフレクションを通じて、メソッド、属性、構築メソッドの取得など、このクラスまたはオブジェクトを操作できます。 、など。

動的プロキシ: JDK 動的プロキシと cglib 動的プロキシ (Spring では動的プロキシ) に分かれています。

静的プロキシ

エージェントとエージェント間の関係は、事前に (コンパイル中に) 決定されます。つまり、エージェント クラスが事前に決定されます。プログラムが実行される、すでに存在する、この状況は静的プロキシと呼ばれます

動的プロキシ

プロキシ クラスはプログラムの実行時に作成されます。言い換えれば、プロキシ クラスは Java コード内で定義されていませんが、Java コード内の「命令」に基づいて実行時に動的に生成されます。

動的プロキシの静的プロキシに対する利点は次のとおりです。

動的プロキシは、各関数を変更するのではなく、プロキシ クラスの関数を均一に簡単に処理 (呼び出し) できます。より柔軟で拡張可能なプロキシ クラス関数。

JDK の動的プロキシ (インターフェイスに依存)

Java の動的プロキシ メカニズムには、2 つの重要なクラスまたはインターフェイスがあります。1 つは InvocationHandler インターフェイスで、もう 1 つは InvocationHandler インターフェイスです。 1 つは Proxy クラスです。

InvocationHandler インターフェイスは動的プロキシ クラス用に実装され、プロキシ オブジェクトの操作を処理します。

Proxy クラスは、この場合にのみ、動的プロキシ クラス インスタンス オブジェクトを作成するために使用されます。オブジェクトが取得され、必要なエージェント メソッドを呼び出すことができます。

動的プロキシのプロキシ クラスは静的プロキシ クラスで変更され、動的プロキシ クラスは InvocationHandler インターフェイスを実装し、Invoke メソッドをオーバーライドします。Invoke メソッドは、受信したプロキシ クラスのメソッドとパラメーターを通じて実行されます。

次の例:

public interface AppService {
	void createApp(String name);
	void deleteApp(String name);
}
//代理类(比如微商代理)
public class AppServiceImpl implements AppService{

	@Override
	public void createApp(String name) {
		System.out.print("App["+name+"] has been created.");
	}

	@Override
	public void deleteApp(String name) {
		System.out.print("App["+name+"] has been delete.");
	}
}

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

public class LoggerInterceptor implements InvocationHandler {
    private Object target; //委托类(被代理类)的实例,比如厂家
    public LoggerInterceptor(Object target){  
        this.target = target;  
    }  
	@Override
	public Object invoke(Object proxy, Method method, Object[] args)throws Throwable {
		System.out.println("Entered "+target.getClass().getName()+"-"+method.getName()+",with arguments{"+args[0]+"}");  
        Object result = method.invoke(target, args);
       //调用目标对象的方法  (调用厂家的方法(createApp)及参数(Kevin Test))
        System.out.println("Before return:"+result);  
        return result;  
	}

}
ログイン後にコピー
import java.lang.reflect.Proxy;

public class test {

public static void main(String[] args) {
    AppService target = new AppServiceImpl();//生成目标对象 (代理类的对象)
    //接下来创建代理对象 
    AppService proxy = (AppService) Proxy.newProxyInstance( 
    target.getClass().getClassLoader(), 
    target.getClass().getInterfaces(), new LoggerInterceptor(target)); 
    proxy.createApp("Kevin Test1"); 
    proxy.deleteApp("Kevin Test2"); 
  }

}/**
* 1、jdk的动态代理实现方式是依赖于接口的,首先使用接口来定义好操作规范。
* 2、通过proxy类产生的代理对象调用被代理对象的操作。
* 3、而这个操作又被分发给InvocationHandler接口的invoke方法具体执行
* 
* 在java的动态代理机制中,有两个重要的类或接口,一个是InvocationHandler接口、另一个则是 Proxy类,这个类和接口是实现我们动态代理所必须用到的。
InvocationHandler接口是给动态代理类实现的,负责处理被代理对象的操作的,而Proxy是用来创建动态代理类实例对象的,因为只有得到了这个对象我们才能调用那些需要代理的方法。
* 
* 此方法的参数含义如下 
proxy:代表动态代理对象 
method:代表正在执行的方法 
args:代表当前执行方法传入的实参 
返回值:表示当前执行方法的返回值
* 
* 如上:
* 使用了Proxy类的newProxyInstance方法生成代理对象,然后用这个对象去调用createApp()和deleteApp()方法,
* 其实系统会将这2个方法分发给invoke()方法区执行。其中proxy对象的类是系统帮我们动态创建了,其实实现了我们的业务接口AppService
* 
*/
ログイン後にコピー

cglib 動的プロキシ (継承メソッド)

MethodInterceptor は cglib 動的プロキシで使用され、ダイナミクスエージェントクラスを実現します。

インターセプター MethodInterceptor では、プロキシ メソッドは MethodProxy の InvokSuper メソッドによって呼び出されます。

MethodProxy クラスは、プロキシ メソッドとプロキシ メソッドのシグネチャを生成します。

JDK ダイナミック プロキシと Cglib ダイナミック プロキシの違い:

1. JDK ダイナミック プロキシはプロキシ オブジェクトのインターフェイスを実装しますが、Cglib はプロキシ オブジェクトを継承します。

2. Cglib は継承メカニズムであるため、final によって変更されたメソッドをプロキシすることはできません。

3. JDK と Cglib はどちらも実行時にバイトコードを生成します。JDK はクラスのバイトコードを直接書き込みますが、Cglib は ASM フレームワークを使用してクラスのバイトコードを書き込みます。また、エージェント クラスの生成は JDK よりも優れています。効率。

4. JDK はリフレクション実装メカニズムを通じてプロキシ メソッドを呼び出しますが、cglib は Fashclass メカニズムを通じてメソッドを直接呼び出します。これはより効率的です。

Fastcalss メカニズム:

プロキシ クラスとプロキシ クラスのクラスを生成します。このクラスは、プロキシ クラスまたはプロキシ クラスのメソッドにインデックスを割り当てます。 。

このインデックスは入力パラメータとして使用され、Fashclass は呼び出されるメソッドを直接見つけて、それを直接呼び出すことができます。これによりリフレクション呼び出しが不要になるため、非常に効率的になります。

以上がJava の動的プロキシとリフレクション メカニズムの詳細な紹介 (コード例)の詳細内容です。詳細については、PHP 中国語 Web サイトの他の関連記事を参照してください。

関連ラベル:
ソース:cnblogs.com
このウェブサイトの声明
この記事の内容はネチズンが自主的に寄稿したものであり、著作権は原著者に帰属します。このサイトは、それに相当する法的責任を負いません。盗作または侵害の疑いのあるコンテンツを見つけた場合は、admin@php.cn までご連絡ください。
人気のチュートリアル
詳細>
最新のダウンロード
詳細>
ウェブエフェクト
公式サイト
サイト素材
フロントエンドテンプレート