Javaダイナミックプロキシクラスは、2つのタイプに分割できます。
静的プロキシ:プログラマーによって作成されるか、特定のツールによってソースコードを自動的に生成してコンパイルします。プログラムが実行される前に、プロキシクラスの.classファイルは既に存在します。
動的プロキシ:プログラムが実行されているときに反射メカニズムを使用して動的に作成されます。
1.最初に、Java Dynamic Proxyを実証します。
今、私たちは次のように言っている単純なビジネスインターフェースを持っています:
コードコピーは次のとおりです。
パッケージtestaop;
{
public void sayshello(string name);
public void talking(文字列名);
}
次のように、implを言う単純な実装クラス:
コードコピーは次のとおりです。
パッケージtestaop;
{
@オーバーライド
public void sayshello(string name){
// TODO自動生成方法スタブ
System.out.println(name + ":みんな!");
}
@オーバーライド
public void talking(string name){
// TODO自動生成方法スタブ
System.out.println(name + ":つまり、調和のとれた社会を構築するために一生懸命努力しなければなりません!");
}
}
私たちが達成したいのは、Helloを言って話している前と後に処理を動的に植え付けることです。
JDK Dynamic Proxyは、主にJava.lang.Reftlectパッケージで2つのクラスを使用しています:ProxyとInvocationHandler。
InvocationHandlerは、このインターフェイスを実装することによりクロスカットロジックを定義し、反射メカニズムを介してターゲットクラスのコードを呼び出し、横断カットロジックとビジネスロジックを動的に織ります。
Proxyは、InvocationHandlerを使用して、特定のインターフェイスに適合し、ターゲットクラスのプロキシオブジェクトを生成するインスタンスを動的に作成します。
次のとおり、InvocationHandlerインスタンスを作成します。
コードコピーは次のとおりです。
パッケージtestaop;
java.lang.reflt.invocationhandlerをインポートします。
java.lang.reflt.methodをインポートします。
パブリッククラスMyInVocationHandlerはInvocationHandlerを実装しています{
プライベートオブジェクトターゲット。
myInvocationHandler(オブジェクトターゲット){
this.target =ターゲット;
}
@オーバーライド
パブリックオブジェクトの呼び出し(オブジェクトプロキシ、メソッドメソッド、オブジェクト[] args)
スローできるスロー{
//ターゲットメソッドの前に実行します
System.out.println( " - - - - - - - - - - 、 - 、...、、、、、、 - 、...」);
System.out.println( "次の人のステージで話してください!");
//ターゲットメソッド呼び出し
オブジェクトobj = method.invoke(ターゲット、args);
//ターゲットメソッドを実行します
System.out.println( "全員拍手と励まし!");
OBJを返します。
}
}
これがテストです:
コードコピーは次のとおりです。
パッケージtestaop;
java.lang.reflt.proxyをインポートします。
パブリッククラスjdkproxytest {
public static void main(string [] args){
//エージェントになりたいターゲットビジネスカテゴリ
ターゲット= new SaingImpl();
//ターゲットクラスとクロスカットクラスを一緒に編む
MyInVocationHandler Handler = new MyInVocationHandler(ターゲット);
//プロキシインスタンスを作成します
proxy =(saking)proxy.newproxyinstance(
Target.getClass()。getClassLoader()、//ターゲットクラスのクラスローダー
Target.getClass()。getInterfaces()、//ターゲットクラスのインターフェイス
ハンドラー); //クロスカットクラス
proxy.sayhello( "xiao ming");
proxy.talking( "xiaoli");
}
}
操作は次のとおりです。
コードコピーは次のとおりです。
- - - - - - - - - - - - - 、、、、、、...
次の人のステージで話してください!
Xiao Ming:みなさん、こんにちは!
誰もが拍手し、励ましました!
- - - - - - - - - - - - - 、、、、、、...
次の人のステージで話してください!
Xiaoli:つまり、私たちは調和のとれた社会を構築するために一生懸命働かなければなりません!
誰もが拍手し、励ましました!
JDKダイナミックプロキシを使用することには大きな制限があります。つまり、ターゲットクラスは、対応するメソッドのインターフェイスを実装する必要があり、インターフェイスのプロキシインスタンスのみを作成することができます。上記のテストクラスの新しいプロキシインスタンスプロキシ法では、このメソッドの2番目のパラメーターがターゲットクラスのインターフェイスであることがわかります。このクラスがインターフェイスを実装していない場合、CGLIBの動的プロキシに依存します。
CGLIBは非常に根本的なバイトコードテクノロジーを採用しています。これにより、クラスのサブクラスを作成し、サブクラスでメソッドインターセプトテクニックを使用して、すべての親クラスメソッド呼び出しを傍受し、状況にクロスカットロジックを埋め込みます。
2。次に、CGLIBダイナミックプロキシを実証します。
まず、私が使用するパッケージを導く必要があります。
最初にプロキシクリエイターCglibproxyを作成します。
コードコピーは次のとおりです。
パッケージtestaop.cglib;
java.lang.reflt.methodをインポートします。
net.sf.cglib.proxy.enhancerをインポートします。
net.sf.cglib.proxy.methodInterceptorをインポートします。
net.sf.cglib.proxy.methodproxyをインポートします。
パブリッククラスcglibproxyはmethodinterceptorを実装します{
Enhancer Enhancer = new Enhancer();
パブリックオブジェクトGetProxy(クラスClazz){
//作成するサブクラスを設定します
Enhance.setsuperclass(clazz);
Enhancer.setCallback(This);
// bytecodeテクノロジーを介してサブクラスインスタンスを動的に作成します
return enthancer.create();
}
@オーバーライド
パブリックオブジェクトインターセプト(オブジェクトobj、メソッドメソッド、オブジェクト[] args、
MethodProxy Proxy)スロー可能{
// TODO自動生成方法スタブ
System.out.println( " - - - - - - - - - - 、 - 、...、、、、、、 - 、...」);
System.out.println( "次の人のステージで話してください!");
//ターゲットメソッド呼び出し
オブジェクトresult = proxy.invokesuper(obj、args);
//ターゲットメソッドを実行します
System.out.println( "全員拍手と励まし!");
返品結果;
}
}
次に、テスト:
コードコピーは次のとおりです。
パッケージtestaop.cglib;
testaop.sayingをインポートします。
testaop.sayingimplをインポートします。
パブリッククラスcglibproxytest {
public static void main(string [] args){
cglibproxy proxy = new cglibproxy();
//サブクラスを動的に生成してプロキシクラスを作成します
ターゲット=(Saing)proxy.getProxy(SakingImpl.Class);
Target.Sayhello( "Xiao Ming");
Target.Talking( "Xiaoli");
}
}
結果は、JDKダイナミックプロキシと違いはありません。
JDK Dynamic ProxyとCGLIB Dynamic Proxyはどちらもランタイム強化であり、クロスカットコードをプロキシクラスに埋め込むことで強化されます。これとは異なり、JDKダイナミックプロキシとCGLIBダイナミックプロキシが強化されるため、このような強化された処理を介してコンパイル期間にクロスカットコードを埋め込むことができます。