動的プロキシの実装
使用モード:プロキシモード。
プロキシモードの機能は、他のオブジェクトがこのオブジェクトへのアクセスを制御するためのプロキシを提供することです。レンタル代理店に似ています。
2つの動的プロキシ:
(1)JDKダイナミックプロキシ。 JDKダイナミックプロキシは、Java内の反射メカニズムによって実装されます。ターゲットクラスは、統一されたインターフェイス(InvocationHandler)に基づいています
(2)cglib動的プロキシ、およびcglibダイナミックプロキシの基礎層がASMの助けを借りて実装されています。 CGLIBなどのサードパーティライブラリによって実装される動的プロキシは、より広く使用されており、効率がより利点があります。
主なアプリケーションフレームワーク:
春のaop、struts2のインターセプター
特定の実装:
1.インターフェイスを定義し、クラスを実装します
パッケージcom.example.service; public interface userservice {public string getName(int id); public Integer Getage(int id);}パッケージcom.example.service.impl; import com.example.service.userservice; public class userserviceimpl emprmenes userservice {public string getname(int id){system.out.println( "------ getName -----"); 「猫」を返します。 } public Integer getage(int id){system.out.println( "------ getage -----"); 10を返します。 }}2。JDKダイナミックプロキシ実装
パッケージcom.example.jdk; import java.lang.refllect.invocationhandler; import java.lang.refllect.method; import java.lang.refllect.proxy; public class myinvocationhandler Invocationhandler {private object target; / ** *デリゲートオブジェクトをバインドしてプロキシクラスを返します * * @paramターゲット * @return */ public object bind(object target){this.target =ターゲット; // proxyオブジェクトを取得しますproxy.newproxyinstance(target.getClass()。getClassLoader()、target.getClass()。getInterfaces()、this); //インターフェイスをバインドする(これは欠陥です、CGLIBはこの欠陥を補います)オブジェクトresult = method.invoke(ターゲット、args); system.out.println( "------ after" + method.getName() + "------");返品結果; } else {object result = method.invoke(ターゲット、args);返品結果; }}}パッケージcom.example.jdk; import com.example.service.userservice;インポートcom.example.service.impl.userserviceimpl;/*** test class*/public class runjdk {public static void main(string [] args){myinvocationhandler proxy = new MyInvocotionHandler(); userservice userserviceproxy =(userservice)proxy.bind(new userserviceimpl()); System.out.println(userserviceproxy.getName(1)); System.out.println(userserviceproxy.getage(1)); }}実行結果:
------ getNameの前----
------ getName -----
------ getNameの後-----
猫
----- getage -----
10
3。CGLIBダイナミックプロキシ実装:
JDKの動的プロキシメカニズムは、インターフェイスを実装するクラスのみをプロキシできますが、インターフェイスを実装できないクラスはJDKの動的プロキシを実装できません。 CGLIBはクラスのプロキシを実装します。その原則は、指定されたターゲットクラスのサブクラスを生成し、メソッド実装の強化を上書きすることです。ただし、継承が使用されるため、最終的に変更されたクラスをプロキシ化することはできません。
CGLIBのコアクラス:
net.sf.cglib.proxy.enhancerメインエンハンスメントクラス
net.sf.cglib.proxy.methodInterceptorメインメソッドはクラスをインターセプトします。これはコールバックインターフェイスのサブインターフェイスであり、ユーザーの実装が必要です。
net.sf.cglib.proxy.methodproxy java.lang.relect.methodクラスのプロキシクラスJDKは、ソースオブジェクトメソッドへの呼び出しを簡単に実装できます。
net.sf.cglib.proxy.methodInterceptorインターフェイスは最も一般的なコールバックタイプであり、プロキシベースのAOPがインターセプトメソッド呼び出しを実装するためによく使用されます。このインターフェイスは、1つのメソッドのみを定義します
パブリックオブジェクトインターセプト(オブジェクトオブジェクト、java.lang.reflt.methodメソッド、
object [] args、methodproxy proxy)スロー可能。
最初のパラメーターはプロキシオブジェクトであり、2番目と3番目のパラメーターは、それぞれメソッドのインターセプトされたメソッドとパラメーターです。元の方法は、java.lang.refllect.methodオブジェクトを使用して一般的な反射コールを使用するか、net.sf.cglib.proxy.methodproxyオブジェクトを使用して呼び出される場合があります。 net.sf.cglib.proxy.methodproxyは通常、より速いため好まれます。
パッケージcom.example.cglib; import org.springframework.cglib.proxy.enhancer; import org.springframework.cglib.proxy.methodInterceptor; Import org.springframework.cglib.proxy.methodproxy; java.lang.reflibp.method; MethodEnterceptor {プライベートオブジェクトターゲット; / ** *プロキシオブジェクトの作成 * * @paramターゲット * @return */ public object getInstance(objectターゲット){this.target =ターゲット; Enhancer Enhancer = new Enhancer(); Enhancer.setsuperclass(this.target.getClass()); //コールバックメソッドEnhancer.setCallback(this); //プロキシオブジェクトを作成しますreturn enthancer.create(); } @Overrideパブリックオブジェクトインターセプト(オブジェクトO、メソッドメソッド、オブジェクト[]オブジェクト、MethodProxy MethodProxy)スロー可能{system.out.println( "++++++++("+methodproxy.getsupername()+"++++++"); System.out.println(method.getName());オブジェクトresult = methodproxy.invokesuper(o、objects); system.out.println( "++++++"+methodproxy.getSuperName()+"+++++++++");返品結果; }}パッケージcom.example.cglib; import com.example.service.userservice;インポートcom.example.service.impl.userserviceimpl;/** * test cglib */public class runcglib {public static void(string [] args){cglibproxy cglibproxy = new cglibproxy(); userservice userservice =(userservice)cglibproxy.getInstance(new userserviceimpl()); userservice.getName(1); userservice.getage(1); }}実行結果:
++++++ cglib $ getName $ 0 ++++++++
getName
------ getName -----
++++++ cglib $ getName $ 0 ++++++++
++++++ cglib $ getage $ 1 +++++++++以前
気をつけて
----- getage -----
++++++ cglib $ getage $ 1 +++++++++
上記はこの記事のすべての内容です。この記事の内容が、すべての人の勉強や仕事に役立つことを願っています。また、wulin.comをもっとサポートしたいと思っています!