AOPの概念
AOP:アスペクト指向のプログラミング(セクション指向プログラミング)、ウィキペディアは次のように説明します。アスペクトは、オブジェクト、クラス、または機能に散らばる断面懸念を説明するために使用される新しいモジュールメカニズムです。横断的な懸念を懸念から分離することは、接線指向のプログラミングの中心的な概念です。フォーカスを分離すると、ビジネスロジックとは無関係に特定のドメインの問題を解決するコードが得られます。ビジネスロジックのコードには、特定のドメインの問題に対するコードへの呼び出しは含まれていません。ビジネスロジックと特定のドメインの問題との関係は、セクションを通じてカプセル化および維持されているため、アプリケーション全体に元々散在していた変更を適切に管理できます。 AOPの観点から見ると、アプリケーションは横断的な懸念とビジネスロジックコードに分けることができます。実際の開発では、これらの横断的な懸念は、多くの場合、ビジネスロジックコードに直接組み込まれています。対面プログラミングは、横断的懸念をビジネスロジックと分離する問題を解決することです。
実装方法:
Springは、JDKダイナミックプロキシをデフォルトでAOPのプロキシとして使用します。欠陥は、ターゲットクラスがインターフェイスを実装する必要があることです。そうしないと、JDKダイナミックプロキシを使用できません。クラスがインターフェイスではなくクラスの場合、SpringはデフォルトでCGLIBプロキシを使用します。 2つの違いについて:JDKダイナミックプロキシはJavaの反射メカニズムを通じて実装され、ターゲットクラスはインターフェイスを実装する必要があり、CGLIBはクラスのプロキシを実装します。その原則は、指定されたターゲットクラスのサブクラスを動的に生成し、メソッド実装の強化をオーバーライドすることですが、継承が使用されるため、最終的な修正クラスをプロキシできません。
JDKダイナミックプロキシ
JDK Dynamic Proxyは、プログラム操作中にターゲットクラスによって実装されたインターフェイスに基づいて、プロキシクラスのクラスファイルを動的に生成します。使用には主に2つのクラスが含まれます。
InvocationHandler Interface: invoke(Object obj,Method method, Object[] args)メソッドを提供して、対応するプロキシロジック実装を提供するためのメソッドを提供します。実際の実装でいくつかの特別な処理を実行でき、パラメーターは
オブジェクトOBJ:プロキシ化されたターゲットクラス
方法方法:実行する必要があるターゲットクラスの方法
Object [] args:ターゲットメソッドのパラメーター
プロキシクラス: newProxyInstance (ClassLoader loader, Class[] interfaces, InvocationHandler h)を提供して、動的プロキシクラスを取得します
サンプルコード:
public Interface Orderservice {public void createOrder(); } public class orderserviceimplはruderservice {@override public void createOrder(){system.out.println( "Orderの作成"); }} public class orderlogger {public void beforecreateorder(){system.out.println( "Orderを作成する前に"); } public void afterCreateOrder(){system.out.println( "Orderを作成後"); }}パッケージcom.sl.aop; import java.lang.Leflt.InvocationHandler; Import java.lang.Reflect.Method; Import Java.lang.Reng.Reflect.Proxy; public class ServiceProxy InvocationHandler {private object targetclass; Private OrderLogger OrderLogger; Public ServiceProxy(Object TargetClass、OrderLogger OrderLogger){this.targetClass =ターゲットクラス; this.ORDERLOGGER = ORDERLOGGER; } // proxy public object getDynamicProxy(){return proxy.newproxyinstance(targetclass.getClass()。getClassLoader()、//このclassloader targetClass.getClass()。 //ダイナミックプロキシコールメソッドは関連するInvocationHandlerであり、最後にこのInvocationHandlerのInvokeメソッドを使用して実際のメソッドを実行します}オブジェクトresult = method.invoke(ターゲットクラス、args); this.OrderLogger.afterCreateOrder();返品結果; }}テストクラス:
パッケージcom.sl.aop; import org.junit.test; public class aoptest {@test public void testdynamicproxy(){Orderserviceimpl serviceimpl = new OrderserviceImpl(); OrderLogger Logger = new OrderLogger(); OrderService Service =(OrderService)new ServiceProxy(serviceImpl、logger).getDynamicProxy(); service.createorder(); }}実行結果:
この点に到達すると、私は実際に少し混乱しています。 Proxy.newProxyInstance()は何を返しますか? Invokeメソッドはどこに呼ばれますか? JDKソースコードを見てみましょう。DKダイナミックプロキシのプロセスがどのように見えるかをご覧ください。
Proxy.newProxyInstance()->Proxy.getProxyClass0()->WeakCache.get()ソースコード内の関数に従って呼び出し、最初に見つけます
weakcache.class:
public v get(k key、p parameter){objects.requirenonnull(parameter); expungestaleentries();オブジェクトcachekey = cachekey.valueof(key、refqueue); //特定のcachekey concurrentmap <object、supply <v >> valuesmap = map.get(cachekey); if(valuesmap == null){concurrentmap <object、supplier <v >> oldvaluesmap = map.putifabsent(cachekey、valuesmap = new concurrenthashmap <>()); if(oldvaluesmap!= null){valuesmap = oldvaluesmap; }} // Subkeyを作成し、ValuesMap ObjectからSubkeyによって保存されている可能性のあるサプライヤー<V>を取得します。サプライヤー<v> supply = valuesmap.get(subkey);工場工場= null; while(true){if(supplier!= null){//サプライヤーは工場またはcachevalue <v> instance v value = supplier.get(); if(value!= null){return値; }} //キャッシュのサプライヤー//またはnullを返したサプライヤー(クリアされたcachevalue //またはcachevalueのインストールに成功しなかった工場になる可能性がある) } if(supplier == null){supplier = valuesmap.putifabsent(subkey、factory); if(supplier == null){// Factory Supplier = Factory; } // else with withine supplierで再試行} else {if(valuesmap.replace(subkey、supplier、factory)){//正常に交換// cackeentry / cleared cacheentry / cleardfactory //工場のサプライヤー=ファクトリー。 } else {//現在のサプライヤーサプライヤーサプライヤー= valuesmap.get(subkey); }}}}関数の戻り値を見ることができます。 V value = supplier.get();それを読み続けて、夕食=工場が実際に工場のオブジェクトであることを見つけてくださいFactory.get()
public synchronized v get(){// serializeアクセス// supplier <v> supplier = valuesmap.get(subkey); if(supplier!= this){//待っている間に何かが変更されました:// cachevalue //に置き換えられたか、障害のために削除された可能性があります - > // nullを返してweakcache.get()をretryに信号を送ります//ループリターンnull; } //まだ私たち(supplier == this)//新しい値v値= nullを作成します。 try {value = objects.requirenonnull(valueFactory.Apply(key、parameter)); }最後に{if(value == null){//失敗valuesmap.remove(subkey、this)で私たちを削除します。 }} //ここで到達する唯一のパスは、非ヌル値のアサート値!= null; // cachevalue(weakreference)cachevalue <v> cachevalue = new cachevalue <>(value); // cachevalueに置き換えてください(これは常に成功する必要があります)if(valuesmap.replace(subkey、this、cachevalue)){// reversemap reversemap.put(cachevalue、boolean.true)にも入れます。 } else {throw new AssertionError( "ここに到達しないでください"); } //新しいcachevalueに正常に置き換えられました - >値を返します// return valueでラップします。 }返品値。次に、割り当てステートメントを直接表示します: value = Objects.requireNonNull(valueFactory.apply(key, parameter));
valueFactoryとは何ですか?
public weakcache(bifunction <k、p、?> subkeyfactory、bifunction <k、p、v> valueFactory){this.subkeyfactory = objects.requirenonnull(subkeyfactory); this.valueFactory = objects.requirenonnull(valueFactory); } private static final weakcache <classloader、class <?> []、class <?>> proxyclasscache = new weakcache <>(new keyFactory()、new ProxyclassFactory()); ValueFactoryはProxyclassFactoryタイプのオブジェクトであることを知ることができ、 ProxyClassFactory. Apply()メソッド
public class <?> apply(classloader roader、class <? for(class <? */ class <?> interfaceClass = null; try {interfaceclass = class.forname(intf.getName()、false、roader); } catch(classNotFoundException e){} if(interfaceClass!= intf){show new elegalargumentException(intf + "はクラスローダーからは見えません"); } / * *クラスオブジェクトが実際に *インターフェイスを表すことを確認します。 */ if(!interfaceclass.isinterface()){新しいIllegalArgumentException(interfaceClass.getName() + "はinterface"ではありません "); } / * *このインターフェイスが複製されていないことを確認します。 */ if(interfaceset.put(interfaceclass、boolean.true)!= null){新しいIllegalargumentException( "Repeated Interface:" + interfaceclass.getName()); }} string proxypkg = null; // int accessflags = modifier.publicでプロキシクラスを定義するパッケージ| modifier.final; / * * *プロキシクラスが同じパッケージで定義されるように、非パブリックプロキシインターフェイスのパッケージを記録します。 *すべての非公開プロキシインターフェイスが同じパッケージにあることを確認します。 */ for(class <? if(!modifier.ispublic(flags)){accessflags = modifier.final;文字列名= intf.getName(); int n = name.lastindexof( '。');文字列pkg =((n == -1)? "":name.substring(0、n + 1)); if(proxypkg == null){proxypkg = pkg; } else if(!pkg.equals(proxypkg)){throw new IllegalargumentException( "異なるパッケージからの非パブリックインターフェイス"); }}}} if(proxypkg == null){//非パブリックプロキシインターフェイスがない場合は、com.sun.proxyパッケージproxypkg = rferxutil.proxy_package + "。"。 "; } / * *生成するプロキシクラスの名前を選択します。 */ long num = nextuniquenumber.getandincrement(); string proxyname = proxypkg + proxyclassnameprefix + num; / * *指定されたプロキシクラスを生成します。 */ byte [] proxyclassfile = proxygenerator.generepproxyclass(proxyname、interfaces、accessflags); try {return defineclass0(loader、proxyname、proxyclassfile、0、proxyclassfile.length); } catch(classformaterror e){ / * *ここでのクラスフォームタラーは、( *プロキシクラス生成コードのバグを除く)、プロキシ *クラスの作成に提供される引数の他の *無効な側面(仮想マシンの制限 *を超えた)があることを意味します。 */新しいIllegalargumentException(e.toString()); }}}重要なポイントを直接描画します:
byte [] proxyclassfile = proxygenerator.generepproxyclass(proxyname、interfaces、accessflags); Return DefineClass0(Loader、Proxyname、Proxyclassfile、0、Proxyclassfile.length);
ProxyGenerator.generateProxyClassを呼び出すと、最後にプロキシクラスが動的に生成されますが、invokeと呼ばれる場所はどこにも発見されていないようです。記事csdn://www.vevb.com/article/118935.htmを参照して、動的に生成されたバイナリバイトコードをローカルに出力し、逆コンパイルしてそれが何であるかを確認してください。テストコードは次のとおりです。
public class aoptest {@test public void testdynamicproxy(){Orderserviceimpl serviceimpl = new OrderserviceImpl(); OrderLogger Logger = new OrderLogger(); OrderService Service =(OrderService)new ServiceProxy(serviceImpl、logger).getDynamicProxy(); service.createorder(); //出力ダイナミックプロキシクラスbytecode createproxyclassfile(); } private static void createproxyclassfile(){string name = "proxyobject"; byte [] data = proxygenerator.generepproxyclass(name、new class [] {Orderservice.class}); fileoutputStream out = null; try {out = new fileoutputStream(name+"。class"); system.out.println((new file( "hello"))。getabsolutepath()); out.write(data); } catch(filenotfoundexception e){e.printstacktrace(); } catch(ioexception e){e.printstacktrace(); }最後に{if(null!= out)try {out.close(); } catch(ioexception e){e.printstacktrace(); }}}}}}Java Decompilerツールを使用して、このバイナリクラスファイルを逆コンパイルします。
特定の動的プロキシクラスproxyobject.java:
com.sl.aop.orderservice;インポートjava.lang.refllect.invocationhandler; Import Java.lang.Reflect.Method; Import java.lang.Reflect.Proxy; Import java.lang.lang.Rang.Reflect.UndEclaredThrowableExceptip;プライベート静的メソッドM2;プライベート静的メソッドM3;プライベート静的メソッドM0; public proxyobject(invocationhandler paraminvocationhandler){super(paraminvocationhandler); } public final boolean equals(object paramobject){try {return((boolean)this.h.invoke(this、m1、new object [] {paramobject}))。booleanvalue(); } catch(error | runtimeexception localerror){localerrorをスロー; } catch(Throwable localThrowable){新しい非宣言されていないthrowableException(localthrowable); }} public final string toString(){try {return(string)this.h.invoke(this、m2、null); } catch(error | runtimeexception localerror){localerrorをスロー; } catch(Throwable localThrowable){新しい非宣言されていないthrowableException(localthrowable); }} public final void createOrder(){try {this.h.invoke(this、m3、null);戻る; } catch(error | runtimeexception localerror){localerrorをスロー; } catch(Throwable localThrowable){新しい非宣言されていないthrowableException(localthrowable); }} public final int hashcode(){try {return((integer)this.h.invoke(this、m0、null))。intvalue(); } catch(error | runtimeexception localerror){localerrorをスロー; } catch(Throwable localThrowable){新しい非宣言されていないthrowableException(localthrowable); }} static {try {m1 = class.forname( "java.lang.object")。getMethod( "equals"、new class [] {class.forname( "java.lang.object")}); m2 = class.forname( "java.lang.object")。getMethod( "toString"、new class [0]); m3 = class.forname( "com.sl.aop.orderservice")。getMethod( "CreateOrder"、new class [0]); m0 = class.forname( "java.lang.object")。getMethod( "hashcode"、new class [0]);戻る; } catch(nosuchmethodexception localnosuchmethodexception){新しいnosuchmethoderror(localnosuchmethodexception.getmessage()); } catch(classNotFoundException localClassNotFoundException){新しいnoclassdeffounderror(localclassnotfoundexception.getMessage()); }}最後に、呼び出しについての部分を見ました:
public final void create Order(){try {this.h.invoke(this、m3、null);戻る; } catch(error | runtimeexception localerror){localerrorをスロー; } catch(Throwable localThrowable){新しい非宣言されていないthrowableException(localthrowable); }}実際、動的プロキシクラスはプロキシから継承し、ターゲットクラスによって継承されたインターフェイスを実装します。 Invokeメソッドは、断面論理の埋め込みを実装するCreateOrderメソッドで呼び出されます。ここでは、プロキシクラスが実際にはクラスではなくインターフェイスプロキシを対象としているため、JDKダイナミックプロキシのターゲットクラスがインターフェイスを実装する必要がある理由も質問に答えます。動的プロキシクラスはプロキシから継承し、Javaは複数の継承を許可しません。動的プロキシクラスとターゲットクラスは、それぞれインターフェイスをそれぞれ実装します。プロキシクラスは、InvocationHandler.Invokeを介してターゲットクラスメソッドへの呼び出しを実現します。
CGLIBダイナミックプロキシ
CGLIBプロキシは、バイトコード処理フレームワークASMを使用してバイトコードを変換し、新しいクラスを生成し、サブクラスのメソッドインターセプトテクニックを使用して、すべての親クラスメソッドをインターセプトして、反射技術を使用したJDKダイナミックプロキシよりも効率的です。ただし、CGLIBの原則は、ターゲットクラスのサブクラスプロキシクラスを動的に生成することであるため、最終として宣言された方法についてはプロキシ化することはできません。その使用には、主に2つのカテゴリが含まれます。
MethodEnterceptorインターフェイス:このインターフェイスは、主にターゲットクラスメソッドの呼び出しを傍受するために使用されるメソッドintercept(Object arg0, Method arg1, Object[] arg2, MethodProxy arg3)を提供します。
Object Arg0、プロキシングされているターゲットクラス
メソッドArg1、委任メソッド
オブジェクト[] arg2、メソッドパラメーター
MethodProxy Arg3:MethodProxyプロキシメソッドオブジェクト
エンハンサークラス:プロキシクラスの作成に使用されます
例:
MethodEnterceptorインターフェイスを実装します。プロキシクラスがメソッドを呼び出すと、CGLIBはMethodEnterceptorインターフェイスインターセプトメソッドを呼び出し、それにより表面ロジックを織ります。
パッケージcom.sl.aop; import java.lang.refllect.method; import org.springframework.cglib.proxy.enhancer; import org.springframework.cglib.proxy.methodInterceptor; Import org.springframework.cglib.proxy.methodproxy methodEnterceptor {private object targetclass; Private OrderLogger OrderLogger; public cglibserviceproxy(Object TargetClass、OrderLogger OrderLogger){this.targetClass =ターゲットクラス; this.ORDERLOGGER = ORDERLOGGER; } / ***プロキシオブジェクトを作成します** / public object getInstance(){Enhancer Enhancer = new Enhancer(); //ターゲットクラス(プロキシ化する必要があるクラス)を設定します。 //コールバックメソッドEnhancer.setCallback(this); //プロキシオブジェクトを作成しますreturn endance.create(); } / ***すべてのターゲットクラスのメソッドをインターセプト** / @Overrideパブリックオブジェクトインターセプト(Object Arg0、Method Arg1、Object [] Arg2、MethodProxy Arg3)スロー可能{OrderLogger.beforeCreateOrder();オブジェクトo1 = arg3.invokesuper(arg0、arg2); OrderLogger.afterCreateOrder(); O1を返します。 }}テスト方法:
public void testdynamicproxy(){system.setProperty(debuggingclasswriter.debug_location_property、 "d:// class"); OrderServiceImpl serviceImpl = new OrderServiceImpl(); OrderLogger Logger = new OrderLogger(); cglibserviceproxy proxy = new cglibserviceproxy(serviceimpl、logger); //サブクラスを生成してプロキシクラスを作成します。 proxyimp.createorder(); }結果:
System.setProperty(DebuggingClassWriter.DEBUG_LOCATION_PROPERTY, "D://class");指定されたディレクトリにcglibダイナミックプロキシクラスを出力し、プロキシクラスの真の顔を逆コンパイルして確認します。
パッケージcom.sl.aop; Import com.sl.aop.orderserviceimpl; import java.lang.reflt.method; import org.springframework.cglib.core.reflectutils; Import org.springframework.cglib.core.signature; import inmoorg.springframework.cglib.cglib.-cglib.-cglib.-cglib.-cglib.cglib.cglib.cglib.cglib.cglib.clib.cglib.clib.cglib.cglib.cglib.cglib.cglib. springframework.cglib.proxy.factory; Import org.springframework.cglib.proxy.methodInterceptor; Import org.springframework.cglib.proxy.methodproxy; orgsodproxy; public class orderserviceimpl $ private $ 17779aa4 extry fortervectionブールcglib $ bound; public staticオブジェクトcglib $ factory_data;プライベート静的最終スレッドローカルcglib $ thread_callbacks;プライベート静的最終コールバック[] cglib $ static_callbacks; Private MethodEnterceptor cglib $ callback_0; private staticオブジェクトcglib $ callback_filter;プライベート静的最終メソッドcglib $ createorder $ 0 $メソッド。プライベート静的最終方法プロキシCGLIB $ CREATEORDER $ 0 $ Proxy; private static finalオブジェクト[] cglib $ emptyargs;プライベート静的最終メソッドcglib $は$ 1 $メソッドに相当します。 Private Static Final MethodProxy CGLIB $は$ 1 $プロキシに相当します。プライベート静的最終メソッドCGLIB $ TOSTRING $ 2 $メソッド。 Private static Final MethodProxy CGLIB $ TOSTRING $ 2 $ Proxy;プライベート静的最終メソッドcglib $ hashcode $ 3 $メソッド。 Private Static Final MethodProxy CGLIB $ HASHCODE $ 3 $ Proxy;プライベート静的最終方法Private static Final MethodProxy CGLIB $ clone $ 4 $ proxy; static void cglib $ statichook1(){cglib $ thread_callbacks = new StreadLocal(); cglib $ emptyargs = new object [0]; class var0 = class.forname( "com.sl.aop.orderserviceimpl $$ enthancerbycglib $ 17779aa4");クラスvar1;方法[] var10000 = reflectutils.findmethods(new String [] {"equals"、 "(ljava/lang/object;)z"、 "tostring"、 "()" ljava/lang/string; "、" hashcode "()"()i "、" clone "、"()ljava/lang/object class.forname( "java.lang.object"))。getDeclaredMethods()); cglib $は$ 1 $ $ method = var10000 [0]に相当します。 cglib $は$ 1 $ $ proxy = methodproxy.create(var1、var0、 "(ljava/lang/object;)z"、 "equals"、 "cglib $ equals $ 1"); cglib $ tostring $ 2 $ method = var10000 [1]; cglib $ tostring $ 2 $ proxy = methodproxy.create(var1、var0、 "()ljava/lang/string;"、 "tostring"、 "cglib $ tostring $ 2"); cglib $ hashcode $ 3 $ method = var10000 [2]; cglib $ hashcode $ 3 $ proxy = methodproxy.create(var1、var0、 "()i"、 "hashcode"、 "cglib $ hashcode $ 3"); cglib $ clone $ 4 $ method = var10000 [3]; cglib $ clone $ 4 $ proxy = methodproxy.create(var1、var0、 "()ljava/lang/object;"、 "clone"、 "cglib $ clone $ 4"); cglib $ create Order $ 0 $ method = reflectutils.findmethods(new String [] {"Create Order"、 "()v"}、(var1 = class.forname( "com.sl.aop.orderserviceimpl")。 cglib $ create Order $ 0 $ proxy = methodproxy.create(var1、var0、 "()v"、 "create Order"、 "cglib $ createOrder $ 0"); } final void cglib $ create Order $ 0(){super.createorder(); } public final void createOrder(){methodEnterceptor var10000 = this.cglib $ callback_0; if(this.cglib $ callback_0 == null){cglib $ bind_callbacks(this); var10000 = this.cglib $ callback_0; } if(var10000!= null){var10000.intercept(this、cglib $ create order $ 0 $ method、cglib $ emptyargs、cglib $ create Order $ 0 $ proxy); } else {super.createorder(); }} final boolean cglib $は$ 1(object var1){return super.equals(var1); } public final boolean equals(object var1){methodinterceptor var10000 = this.cglib $ callback_0; if(this.cglib $ callback_0 == null){cglib $ bind_callbacks(this); var10000 = this.cglib $ callback_0; } if(var10000!= null){object var2 = var10000.intercept(this、cglib $は$ 1 $メソッド、new object [] {var1}、cglib $は$ 1 $ proxyに等しい); return var2 == null?false:((boolean)var2).booleanvalue(); } else {return super.equals(var1); }} final string cglib $ tostring $ 2(){return super.tostring(); } public final String toString(){methodEnterceptor var10000 = this.cglib $ callback_0; if(this.cglib $ callback_0 == null){cglib $ bind_callbacks(this); var10000 = this.cglib $ callback_0; } return var10000!= null?(string)var10000.intercept(this、cglib $ tostring $ 2 $ method、cglib $ emptyargs、cglib $ tostring $ 2 $ proxy):super.tostring(); } final int cglib $ hashcode $ 3(){return super.hashcode(); } public final int hashcode(){methodEnterceptor var10000 = this.cglib $ callback_0; if(this.cglib $ callback_0 == null){cglib $ bind_callbacks(this); var10000 = this.cglib $ callback_0; } if(var10000!= null){object var1 = var10000.intercept(this、cglib $ hashcode $ 3 $ method、cglib $ emptyargs、cglib $ hashcode $ 3 $ proxy); var1 == null?0:((number)var1).intvalue(); } else {return super.hashcode(); }}最終オブジェクトcglib $ clone $ 4()throws clonenotsupportedexception {return super.clone(); }保護された最終オブジェクトclone()throws clonenotsupportedexception {MethodEnterceptor var10000 = this.cglib $ callback_0; if(this.cglib $ callback_0 == null){cglib $ bind_callbacks(this); var10000 = this.cglib $ callback_0; } return var10000!= null?var10000.intercept(this、cglib $ clone $ 4 $ method、cglib $ emptyargs、cglib $ clone $ 4 $ proxy):super.clone(); } public static methodproxy cglib $ findmethodproxy(signature var0){string var10000 = var0.toString(); switch(var10000.hashcode()){case -2138148221:if(var10000.equals( "createorder()v")){return cglib $ createorder $ 0 $ proxy; } 壊す;ケース-508378822:if(var10000.equals( "clone()ljava/lang/object;")){return cglib $ clone $ 4 $ proxy; } 壊す;ケース1826985398:if(var10000.equals( "equals(ljava/lang/object;)z")){return cglib $は$ 1 $ proxyに等しい。 } 壊す;ケース1913648695:if(var10000.equals( "toString()ljava/lang/string;"))){return cglib $ tostring $ 2 $ proxy; } 壊す;ケース1984935277:if(var10000.equals( "hashcode()i")){return cglib $ hashcode $ 3 $ proxy; }} nullを返します。 } public OrderserviceImpl $$ enthancerbycglib $ 17779aa4(){cglib $ bind_callbacks(this); } public static void cglib $ set_thread_callbacks(callback [] var0){cglib $ thread_callbacks.set(var0); } public static void cglib $ set_static_callbacks(callback [] var0){cglib $ static_callbacks = var0; } private static final void cglib $ bind_callbacks(object var0){orderserviceimpl $$ enthancerbycglib $$ 17779AA4 var1 =(orderserviceimpl $$ enthancerbycglib $ 1779AA4)var0; if(!var1.cglib $ bound){var1.cglib $ bound = true;オブジェクトvar10000 = cglib $ thread_callbacks.get(); if(var10000 == null){var10000 = cglib $ static_callbacks; if(cglib $ static_callbacks == null){return; }} var1.cglib $ callback_0 =(methodinterceptor)((callback [])var10000)[0]; }} public Object newInstance(callback [] var1){cglib $ set_thread_callbacks(var1); OrderServiceImpl $$ enthancerbycglib $ 17779AA4 var10000 = new OrderServiceImpl $$ enthancerbycglib $ 17779AA4(); cglib $ set_thread_callbacks((callback [])null); var10000を返します。 } public Object newInstance(callback var1){cglib $ set_thread_callbacks(new Callback [] {var1}); OrderServiceImpl $$ enthancerbycglib $ 17779AA4 var10000 = new OrderServiceImpl $$ enthancerbycglib $ 17779AA4(); cglib $ set_thread_callbacks((callback [])null); var10000を返します。 } public object newInstance(class [] var1、object [] var2、callback [] var3){cglib $ set_thread_callbacks(var3); OrderServiceImpl $$ enthancerbycglib $$ 17779AA4 var10000 = new OrderServiceImpl $$ hancerbycglib $$ 17779AA4; switch(var1.length){case 0:var10000。<init>(); cglib $ set_thread_callbacks((callback [])null); var10000を返します。デフォルト:新しいIllegalargumentException( "Constructor Not Found")をスローします。 }} public callback getCallback(int var1){cglib $ bind_callbacks(this); MethodEnterceptor var10000; switch(var1){case 0:var10000 = this.cglib $ callback_0;壊す;デフォルト:var10000 = null; } var10000を返します。 } public void setCallback(int var1、callback var2){switch(var1){case 0:this.cglib $ callback_0 =(methodinterceptor)var2;デフォルト:}} public callback [] getCallbacks(){cglib $ bind_callbacks(this); new callbackを返します[] {this.cglib $ callback_0}; } public void setCallbacks(callback [] var1){this.cglib $ callback_0 =(methodinterceptor)var1 [0]; } static {cglib $ statichook1(); }}上記のコードでは、Proxy Class Class -OrderServiceImpl $$ EnhancerBycglib $$ 17779AA4がターゲットクラスのOrderServiceImplを継承し、インターフェイスファクトリを実装することがわかります。プロキシクラスでは、2つの方法CGLIB $ CREATEORDER $ 0とCREATEORDERが生成されます。
CGLIB $ CREATEORDER $ 0メソッドは、ターゲットクラスのsupper.createOrderを直接呼び出します
CreateOrderメソッドは、MethodEnterceptorインターフェイスのコールバックが実装されているかどうかを最初にカウントします。それが存在する場合、MethodEnterceptorインターフェイスインターセプトメソッドが呼び出されます。以前の実装によれば、ターゲットへの呼び出しが実装されています。 Object o1 = arg3.invokeSuper(arg0, arg2)実装されています。 InvokeSuperは、実際には、直接呼び出されるプロキシクラスのCGLIB$createOrder$0()メソッドであり、ターゲットクラスの作成は最終的に呼び出されます。
2つのエージェントの比較
JDKダイナミックプロキシ:
プロキシクラスとデリゲートクラスは、同じインターフェイスを実装します。主に、プロキシクラスを介してInvocationHandlerを実装し、Invokeメソッドを書き直して動的プロキシを実行します。この方法は、Invokeメソッドで強化されます。メソッドの利点:ハードコーディングされたインターフェイスは必要ありません。コードの再利用率は高くなっています。短所:インターフェイスで実装できるデリゲートクラスのみ
cglibダイナミックプロキシ:
プロキシクラスは、デリゲートクラスを親クラスとして採用し、その中のファイナル以外のデリゲートメソッドの2つの方法を作成します。 1つは、Delegate Method Signatureと同じ方法であり、メソッドのSuperを介してデリゲートメソッドを呼び出します。もう1つは、プロキシクラスに固有の方法です。プロキシメソッドでは、MethodEnterceptorインターフェイスを実装するオブジェクトがあるかどうかを決定します。それが存在する場合、インターセプトメソッドは、デリゲートメソッドをプロキシするために呼び出されます。利点:実行時にクラスまたはインターフェイスの操作を強化することができ、デリゲートクラスはインターフェイスを実装する必要はありません。短所:最終クラスと最終的な方法をプロキシできません。
要約します
上記は、この記事のコンテンツ全体です。この記事の内容には、すべての人の研究や仕事に特定の参照値があることを願っています。ご質問がある場合は、メッセージを残してコミュニケーションをとることができます。 wulin.comへのご支援ありがとうございます。