本篇內(nèi)容主要講解“Spring中AOP的概念和JDK動(dòng)態(tài)代理的實(shí)現(xiàn)方式”,感興趣的朋友不妨來(lái)看看。本文介紹的方法操作簡(jiǎn)單快捷,實(shí)用性強(qiáng)。下面就讓小編來(lái)帶大家學(xué)習(xí)“Spring中AOP的概念和JDK動(dòng)態(tài)代理的實(shí)現(xiàn)方式”吧!
網(wǎng)站建設(shè)哪家好,找創(chuàng)新互聯(lián)公司!專注于網(wǎng)頁(yè)設(shè)計(jì)、網(wǎng)站建設(shè)、微信開(kāi)發(fā)、小程序設(shè)計(jì)、集團(tuán)企業(yè)網(wǎng)站建設(shè)等服務(wù)項(xiàng)目。為回饋新老客戶創(chuàng)新互聯(lián)還提供了蘭考免費(fèi)建站歡迎大家使用!
AOP的概念
AOP:Aspect-Oriented Programming(面向切面編程),維基百科的解釋如下:Aspect是一種新的模塊化機(jī)制,用來(lái)描述分散在對(duì)象、類(lèi)或者函數(shù)中的橫切關(guān)注點(diǎn),從關(guān)注點(diǎn)中分離出橫切關(guān)注點(diǎn)是面向切面的程序設(shè)計(jì)的核心概念。分離關(guān)注點(diǎn)使解決特定領(lǐng)域問(wèn)題的代碼從業(yè)務(wù)邏輯中獨(dú)立出來(lái),業(yè)務(wù)邏輯的代碼中不在含有針對(duì)特定領(lǐng)域問(wèn)題的代碼的調(diào)用,業(yè)務(wù)邏輯同特定領(lǐng)域問(wèn)題的關(guān)系通過(guò)切面來(lái)封裝、維護(hù),這樣原本分散在整個(gè)應(yīng)用程序中的變動(dòng)就可以很好地管理起來(lái)。從AOP的角度,應(yīng)用可以分為橫切關(guān)注點(diǎn)和業(yè)務(wù)邏輯代碼,實(shí)際開(kāi)發(fā)中,這些橫切關(guān)注點(diǎn)往往會(huì)直接嵌入到業(yè)務(wù)邏輯代碼中,面向切面編程就是要解決把橫切關(guān)注點(diǎn)與業(yè)務(wù)邏輯相分離
實(shí)現(xiàn)方式:
Spring默認(rèn)使用 JDK 動(dòng)態(tài)代理作為AOP的代理,缺陷是目標(biāo)類(lèi)的類(lèi)必須實(shí)現(xiàn)接口,否則不能使用JDK動(dòng)態(tài)代理。如果需要代理的是類(lèi)而不是接口,那么Spring會(huì)默認(rèn)使用CGLIB代理,關(guān)于兩者的區(qū)別:jdk動(dòng)態(tài)代理是通過(guò)java的反射機(jī)制來(lái)實(shí)現(xiàn)的,目標(biāo)類(lèi)必須要實(shí)現(xiàn)接口,cglib是針對(duì)類(lèi)來(lái)實(shí)現(xiàn)代理的,他的原理是動(dòng)態(tài)的為指定的目標(biāo)類(lèi)生成一個(gè)子類(lèi),并覆蓋其中方法實(shí)現(xiàn)增強(qiáng),但因?yàn)椴捎玫氖抢^承,所以不能對(duì)final修飾的類(lèi)進(jìn)行代理。
JDK動(dòng)態(tài)代理
Jdk動(dòng)態(tài)代理是在程序運(yùn)行過(guò)程中,根據(jù)目標(biāo)類(lèi)實(shí)現(xiàn)的接口來(lái)動(dòng)態(tài)生成代理類(lèi)的class文件,使用主要涉及兩個(gè)類(lèi):
InvocationHandler接口: 它提供了一個(gè)invoke(Object obj,Method method, Object[] args)
方法供實(shí)現(xiàn)者提供相應(yīng)的代理邏輯的實(shí)現(xiàn)??梢詫?duì)實(shí)際的實(shí)現(xiàn)進(jìn)行一些特殊的處理其中參數(shù)
Object obj :被代理的目標(biāo)類(lèi)
Method method: 需要執(zhí)行的目標(biāo)類(lèi)的方法
Object[] args :目標(biāo)方法的參數(shù)
Proxy類(lèi):提供一個(gè)方法newProxyInstance (ClassLoader loader, Class[] interfaces, InvocationHandler h)
來(lái)獲得動(dòng)態(tài)代理類(lèi)
示例代碼:
public interface OrderService { public void createOrder(); }
public class OrderServiceImpl implements OrderService { @Override public void createOrder() { System.out.println("creating order"); } }
public class OrderLogger { public void beforeCreateOrder(){ System.out.println("before create order"); } public void afterCreateOrder(){ System.out.println("after create order"); } }
package com.sl.aop; import java.lang.reflect.InvocationHandler; import java.lang.reflect.Method; import java.lang.reflect.Proxy; public class ServiceProxy implements InvocationHandler { private Object targetClass; private OrderLogger orderLogger; public ServiceProxy(Object targetClass,OrderLogger orderLogger) { this.targetClass = targetClass; this.orderLogger = orderLogger; } //獲取代理 public Object GetDynamicProxy() { return Proxy.newProxyInstance(targetClass.getClass().getClassLoader(), //通過(guò)這個(gè)ClassLoader生成代理對(duì)象 targetClass.getClass().getInterfaces(),//代理類(lèi)已實(shí)現(xiàn)的接口 this); //動(dòng)態(tài)代理調(diào)用方法是關(guān)聯(lián)的InvocationHandler,最終通過(guò)此InvocationHandler的invoke方法執(zhí)行真正的方法 } //實(shí)現(xiàn)相應(yīng)的代理邏輯 @Override public Object invoke(Object proxy, Method method, Object[] args) throws Throwable { this.orderLogger.beforeCreateOrder(); Object result= method.invoke(targetClass, args); this.orderLogger.afterCreateOrder(); return result; } }
測(cè)試類(lèi):
package 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(); } }
運(yùn)行結(jié)果:
到這個(gè)其實(shí)還是有點(diǎn)困惑,Proxy.newProxyInstance()
這個(gè)返回的是什么? Invoke方法在哪里調(diào)用的?我們看一下JDK源碼:看看DK動(dòng)態(tài)代理的過(guò)程是什么樣的:
根據(jù)源碼內(nèi)部的函數(shù)調(diào)用Proxy.newProxyInstance()->Proxy.getProxyClass0()->WeakCache.get()
,先定位到
WeakCache.class:
public V get(K key, P parameter) { Objects.requireNonNull(parameter); expungeStaleEntries(); Object cacheKey = CacheKey.valueOf(key, refQueue); // lazily install the 2nd level valuesMap for the particular cacheKey ConcurrentMap
可以看到函數(shù)return value; 而 V value = supplier.get();
繼續(xù)往下讀可以發(fā)現(xiàn) supper=factory,實(shí)際上是一個(gè)Factory對(duì)象,那么繼續(xù)查看Factory.get()
方法
public synchronized V get() { // serialize access // re-check Suppliersupplier = valuesMap.get(subKey); if (supplier != this) { // something changed while we were waiting: // might be that we were replaced by a CacheValue // or were removed because of failure -> // return null to signal WeakCache.get() to retry // the loop return null; } // else still us (supplier == this) // create new value V value = null; try { value = Objects.requireNonNull(valueFactory.apply(key, parameter)); } finally { if (value == null) { // remove us on failure valuesMap.remove(subKey, this); } } // the only path to reach here is with non-null value assert value != null; // wrap value with CacheValue (WeakReference) CacheValue cacheValue = new CacheValue<>(value); // try replacing us with CacheValue (this should always succeed) if (valuesMap.replace(subKey, this, cacheValue)) { // put also in reverseMap reverseMap.put(cacheValue, Boolean.TRUE); } else { throw new AssertionError("Should not reach here"); } // successfully replaced us with new CacheValue -> return the value // wrapped by it return value; }
Return value;那么直接查看賦值語(yǔ)句:value = Objects.requireNonNull(valueFactory.apply(key, parameter));
valueFactory又什么鬼?
public WeakCache(BiFunctionsubKeyFactory, BiFunction valueFactory) { this.subKeyFactory = Objects.requireNonNull(subKeyFactory); this.valueFactory = Objects.requireNonNull(valueFactory); } private static final WeakCache [], Class>> proxyClassCache = new WeakCache<>(new KeyFactory(), new ProxyClassFactory());
可以知道valueFactory是ProxyClassFactory類(lèi)型對(duì)象,直接查看ProxyClassFactory. Apply()
方法
public Class> apply(ClassLoader loader, Class>[] interfaces) { Map, Boolean> interfaceSet = new IdentityHashMap<>(interfaces.length); for (Class> intf : interfaces) { /* * Verify that the class loader resolves the name of this * interface to the same Class object. */ Class> interfaceClass = null; try { interfaceClass = Class.forName(intf.getName(), false, loader); } catch (ClassNotFoundException e) { } if (interfaceClass != intf) { throw new IllegalArgumentException( intf + " is not visible from class loader"); } /* * Verify that the Class object actually represents an * interface. */ if (!interfaceClass.isInterface()) { throw new IllegalArgumentException( interfaceClass.getName() + " is not an interface"); } /* * Verify that this interface is not a duplicate. */ if (interfaceSet.put(interfaceClass, Boolean.TRUE) != null) { throw new IllegalArgumentException( "repeated interface: " + interfaceClass.getName()); } } String proxyPkg = null; // package to define proxy class in int accessFlags = Modifier.PUBLIC | Modifier.FINAL; /* * Record the package of a non-public proxy interface so that the * proxy class will be defined in the same package. Verify that * all non-public proxy interfaces are in the same package. */ for (Class> intf : interfaces) { int flags = intf.getModifiers(); if (!Modifier.isPublic(flags)) { accessFlags = Modifier.FINAL; String name = intf.getName(); int n = name.lastIndexOf('.'); String pkg = ((n == -1) ? "" : name.substring(0, n + 1)); if (proxyPkg == null) { proxyPkg = pkg; } else if (!pkg.equals(proxyPkg)) { throw new IllegalArgumentException( "non-public interfaces from different packages"); } } } if (proxyPkg == null) { // if no non-public proxy interfaces, use com.sun.proxy package proxyPkg = ReflectUtil.PROXY_PACKAGE + "."; } /* * Choose a name for the proxy class to generate. */ long num = nextUniqueNumber.getAndIncrement(); String proxyName = proxyPkg + proxyClassNamePrefix + num; /* * Generate the specified proxy class. */ byte[] proxyClassFile = ProxyGenerator.generateProxyClass( proxyName, interfaces, accessFlags); try { return defineClass0(loader, proxyName, proxyClassFile, 0, proxyClassFile.length); } catch (ClassFormatError e) { /* * A ClassFormatError here means that (barring bugs in the * proxy class generation code) there was some other * invalid aspect of the arguments supplied to the proxy * class creation (such as virtual machine limitations * exceeded). */ throw new IllegalArgumentException(e.toString()); } } }
直接畫(huà)重點(diǎn):
byte[] proxyClassFile = ProxyGenerator.generateProxyClass( proxyName, interfaces, accessFlags); return defineClass0(loader, proxyName, proxyClassFile, 0, proxyClassFile.length);
調(diào)用ProxyGenerator.generateProxyClass
最終動(dòng)態(tài)生成一個(gè)代理類(lèi),但是似乎并未找到何處調(diào)用了invoke方法;參考CSDN: https://www.jb51.net/article/118935.htm這篇文章,嘗試將這個(gè)動(dòng)態(tài)生成的二進(jìn)制字節(jié)碼輸出到本地,并反編譯出來(lái)一看究竟,測(cè)試代碼如下:
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(); //輸出動(dòng)態(tài)代理類(lèi)字節(jié)碼 createProxyClassFile(); } private static void createProxyClassFile(){ String name = "ProxyObject"; byte[] data = ProxyGenerator.generateProxyClass(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(); }finally { if(null!=out) try { out.close(); } catch (IOException e) { e.printStackTrace(); } } } }
使用java Decompiler工具將這個(gè)二進(jìn)制class文件反編譯查看:
具體動(dòng)態(tài)代理類(lèi)ProxyObject.java:
import com.sl.aop.OrderService; import java.lang.reflect.InvocationHandler; import java.lang.reflect.Method; import java.lang.reflect.Proxy; import java.lang.reflect.UndeclaredThrowableException; public final class ProxyObject extends Proxy implements OrderService { private static Method m1; private static Method m2; private static Method m3; private static Method 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) { throw localError; } catch (Throwable localThrowable) { throw new UndeclaredThrowableException(localThrowable); } } public final String toString() { try { return (String)this.h.invoke(this, m2, null); } catch (Error|RuntimeException localError) { throw localError; } catch (Throwable localThrowable) { throw new UndeclaredThrowableException(localThrowable); } } public final void createOrder() { try { this.h.invoke(this, m3, null); return; } catch (Error|RuntimeException localError) { throw localError; } catch (Throwable localThrowable) { throw new UndeclaredThrowableException(localThrowable); } } public final int hashCode() { try { return ((Integer)this.h.invoke(this, m0, null)).intValue(); } catch (Error|RuntimeException localError) { throw localError; } catch (Throwable localThrowable) { throw new UndeclaredThrowableException(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]); return; } catch (NoSuchMethodException localNoSuchMethodException) { throw new NoSuchMethodError(localNoSuchMethodException.getMessage()); } catch (ClassNotFoundException localClassNotFoundException) { throw new NoClassDefFoundError(localClassNotFoundException.getMessage()); } }
終于看到關(guān)于invoke的部分了:
public final void createOrder() { try { this.h.invoke(this, m3, null); return; } catch (Error|RuntimeException localError) { throw localError; } catch (Throwable localThrowable) { throw new UndeclaredThrowableException(localThrowable); } }
實(shí)際上動(dòng)態(tài)代理類(lèi)繼承自Proxy,并且實(shí)現(xiàn)了目標(biāo)類(lèi)繼承的接口,在createOrder方法中調(diào)用了invoke方法,實(shí)現(xiàn)了切面邏輯的植入,這里也回答了一個(gè)問(wèn)題,為什么JDK動(dòng)態(tài)代理的目標(biāo)類(lèi)必須是實(shí)現(xiàn)接口的,因?yàn)榇眍?lèi)其實(shí)是針對(duì)接口代理,而不是針對(duì)類(lèi)來(lái)代理的,動(dòng)態(tài)代理類(lèi)自己繼承自Proxy,Java也不允許多重繼承。動(dòng)態(tài)代理類(lèi)和目標(biāo)類(lèi)其實(shí)是各自實(shí)現(xiàn)了接口,代理類(lèi)通過(guò)InvocationHandler.invoke實(shí)現(xiàn)對(duì)目標(biāo)類(lèi)方法的調(diào)用。
CGLIB動(dòng)態(tài)代理
CGLIB代理是通過(guò)使用一個(gè)字節(jié)碼處理框架ASM,來(lái)轉(zhuǎn)換字節(jié)碼并生成新的類(lèi),并在子類(lèi)中采用方法攔截的技術(shù)攔截所有父類(lèi)方法的調(diào)用,實(shí)現(xiàn)織如如橫切邏輯 ,效率上比使用反射技術(shù)的JDK動(dòng)態(tài)代理要高,但是由于CGLIB的原理是動(dòng)態(tài)為目標(biāo)類(lèi)生成子類(lèi)代理類(lèi),所以不能為聲明為final的方法進(jìn)行代理。其使用主要涉及兩個(gè)類(lèi):
MethodInterceptor接口:該接口提供一個(gè)方法intercept(Object arg0, Method arg1, Object[] arg2, MethodProxy arg3)
主要用于攔截目標(biāo)類(lèi)方法的調(diào)用
Object arg0, :被代理的目標(biāo)類(lèi)
Method arg1, 委托方法
Object[] arg2, 方法參數(shù)
MethodProxy arg3 :代理方法的MethodProxy對(duì)象
Enhancer類(lèi):用于創(chuàng)建代理類(lèi)
示例:
實(shí)現(xiàn)MethodInterceptor接口,代理類(lèi)在調(diào)用方法時(shí),CGLIB會(huì)回調(diào)MethodInterceptor接口intercept方法,從而織入切面邏輯。
package com.sl.aop; import java.lang.reflect.Method; import org.springframework.cglib.proxy.Enhancer; import org.springframework.cglib.proxy.MethodInterceptor; import org.springframework.cglib.proxy.MethodProxy; public class CglibServiceProxy implements MethodInterceptor { private Object targetClass; private OrderLogger orderLogger; public CglibServiceProxy(Object targetClass,OrderLogger orderLogger) { this.targetClass = targetClass; this.orderLogger = orderLogger; } /** * 創(chuàng)建代理對(duì)象 * */ public Object getInstance() { Enhancer enhancer = new Enhancer(); //設(shè)置目標(biāo)類(lèi)(需要被代理的類(lèi)) enhancer.setSuperclass(this.targetClass.getClass()); // 回調(diào)方法 enhancer.setCallback(this); // 創(chuàng)建代理對(duì)象 return enhancer.create(); } /** * 攔截所有目標(biāo)類(lèi)方法的調(diào)用 * */ @Override public Object intercept(Object arg0, Method arg1, Object[] arg2, MethodProxy arg3) throws Throwable { orderLogger.beforeCreateOrder(); Object o1 = arg3.invokeSuper(arg0, arg2); orderLogger.afterCreateOrder(); return o1; } }
測(cè)試方法:
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); //通過(guò)生成子類(lèi)的方式創(chuàng)建代理類(lèi) OrderServiceImpl proxyImp = (OrderServiceImpl)proxy.getInstance(); proxyImp.createOrder(); }
結(jié)果:
System.setProperty(DebuggingClassWriter.DEBUG_LOCATION_PROPERTY, "D:\\class");
將cglib動(dòng)態(tài)代理類(lèi)輸出到指定目錄,反編譯查看一下代理類(lèi)真面目:
package com.sl.aop; import com.sl.aop.OrderServiceImpl; import java.lang.reflect.Method; import org.springframework.cglib.core.ReflectUtils; import org.springframework.cglib.core.Signature; import org.springframework.cglib.proxy.Callback; import org.springframework.cglib.proxy.Factory; import org.springframework.cglib.proxy.MethodInterceptor; import org.springframework.cglib.proxy.MethodProxy; public class OrderServiceImpl$$EnhancerByCGLIB$$17779aa4 extends OrderServiceImpl implements Factory { private boolean CGLIB$BOUND; public static Object CGLIB$FACTORY_DATA; private static final ThreadLocal CGLIB$THREAD_CALLBACKS; private static final Callback[] CGLIB$STATIC_CALLBACKS; private MethodInterceptor CGLIB$CALLBACK_0; private static Object CGLIB$CALLBACK_FILTER; private static final Method CGLIB$createOrder$0$Method; private static final MethodProxy CGLIB$createOrder$0$Proxy; private static final Object[] CGLIB$emptyArgs; private static final Method CGLIB$equals$1$Method; private static final MethodProxy CGLIB$equals$1$Proxy; private static final Method CGLIB$toString$2$Method; private static final MethodProxy CGLIB$toString$2$Proxy; private static final Method CGLIB$hashCode$3$Method; private static final MethodProxy CGLIB$hashCode$3$Proxy; private static final Method CGLIB$clone$4$Method; private static final MethodProxy CGLIB$clone$4$Proxy; static void CGLIB$STATICHOOK1() { CGLIB$THREAD_CALLBACKS = new ThreadLocal(); CGLIB$emptyArgs = new Object[0]; Class var0 = Class.forName("com.sl.aop.OrderServiceImpl$$EnhancerByCGLIB$$17779aa4"); Class var1; Method[] var10000 = ReflectUtils.findMethods(new String[]{"equals", "(Ljava/lang/Object;)Z", "toString", "()Ljava/lang/String;", "hashCode", "()I", "clone", "()Ljava/lang/Object;"}, (var1 = Class.forName("java.lang.Object")).getDeclaredMethods()); CGLIB$equals$1$Method = var10000[0]; CGLIB$equals$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$createOrder$0$Method = ReflectUtils.findMethods(new String[]{"createOrder", "()V"}, (var1 = Class.forName("com.sl.aop.OrderServiceImpl")).getDeclaredMethods())[0]; CGLIB$createOrder$0$Proxy = MethodProxy.create(var1, var0, "()V", "createOrder", "CGLIB$createOrder$0"); } final void CGLIB$createOrder$0() { super.createOrder(); } public final void createOrder() { MethodInterceptor 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$createOrder$0$Method, CGLIB$emptyArgs, CGLIB$createOrder$0$Proxy); } else { super.createOrder(); } } final boolean CGLIB$equals$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$equals$1$Method, new Object[]{var1}, CGLIB$equals$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() { MethodInterceptor 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() { 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 var1 = var10000.intercept(this, CGLIB$hashCode$3$Method, CGLIB$emptyArgs, CGLIB$hashCode$3$Proxy); return var1 == null?0:((Number)var1).intValue(); } else { return super.hashCode(); } } final Object CGLIB$clone$4() throws CloneNotSupportedException { return super.clone(); } protected final Object clone() throws CloneNotSupportedException { MethodInterceptor 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; } break; case -508378822: if(var10000.equals("clone()Ljava/lang/Object;")) { return CGLIB$clone$4$Proxy; } break; case 1826985398: if(var10000.equals("equals(Ljava/lang/Object;)Z")) { return CGLIB$equals$1$Proxy; } break; case 1913648695: if(var10000.equals("toString()Ljava/lang/String;")) { return CGLIB$toString$2$Proxy; } break; case 1984935277: if(var10000.equals("hashCode()I")) { return CGLIB$hashCode$3$Proxy; } } return null; } public OrderServiceImpl$$EnhancerByCGLIB$$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$$EnhancerByCGLIB$$17779aa4 var1 = (OrderServiceImpl$$EnhancerByCGLIB$$17779aa4)var0; if(!var1.CGLIB$BOUND) { var1.CGLIB$BOUND = true; Object 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$$EnhancerByCGLIB$$17779aa4 var10000 = new OrderServiceImpl$$EnhancerByCGLIB$$17779aa4(); CGLIB$SET_THREAD_CALLBACKS((Callback[])null); return var10000; } public Object newInstance(Callback var1) { CGLIB$SET_THREAD_CALLBACKS(new Callback[]{var1}); OrderServiceImpl$$EnhancerByCGLIB$$17779aa4 var10000 = new OrderServiceImpl$$EnhancerByCGLIB$$17779aa4(); CGLIB$SET_THREAD_CALLBACKS((Callback[])null); return var10000; } public Object newInstance(Class[] var1, Object[] var2, Callback[] var3) { CGLIB$SET_THREAD_CALLBACKS(var3); OrderServiceImpl$$EnhancerByCGLIB$$17779aa4 var10000 = new OrderServiceImpl$$EnhancerByCGLIB$$17779aa4; switch(var1.length) { case 0: var10000.(); CGLIB$SET_THREAD_CALLBACKS((Callback[])null); return var10000; default: throw new IllegalArgumentException("Constructor not found"); } } public Callback getCallback(int var1) { CGLIB$BIND_CALLBACKS(this); MethodInterceptor var10000; switch(var1) { case 0: var10000 = this.CGLIB$CALLBACK_0; break; default: var10000 = null; } return var10000; } public void setCallback(int var1, Callback var2) { switch(var1) { case 0: this.CGLIB$CALLBACK_0 = (MethodInterceptor)var2; default: } } public Callback[] getCallbacks() { CGLIB$BIND_CALLBACKS(this); return new Callback[]{this.CGLIB$CALLBACK_0}; } public void setCallbacks(Callback[] var1) { this.CGLIB$CALLBACK_0 = (MethodInterceptor)var1[0]; } static { CGLIB$STATICHOOK1(); } }
上面的代碼可以看到代理類(lèi)OrderServiceImpl$$EnhancerByCGLIB$$17779aa4 繼承目標(biāo)類(lèi)OrderServiceImpl并且實(shí)現(xiàn)了接口Factory,代理類(lèi)中關(guān)于createorder生成了兩個(gè)方法CGLIB$createOrder$0和createOrder:
CGLIB$createOrder$0方法內(nèi)部直接調(diào)用目標(biāo)類(lèi)的supper.createOrder
createOrder方法內(nèi)部首先盤(pán)點(diǎn)否實(shí)現(xiàn)了MethodInterceptor接口的callback,如果存在則調(diào)用MethodInterceptor接口攔截方法intercept,根據(jù)前面的實(shí)現(xiàn)intercept方法內(nèi)部實(shí)現(xiàn)了對(duì)目標(biāo)方法的調(diào)用Object o1 = arg3.invokeSuper(arg0, arg2)
,invokeSuper內(nèi)部實(shí)際上是直接調(diào)用的代理類(lèi)的CGLIB$createOrder$0()
方法,最終調(diào)用了目標(biāo)類(lèi)createOrder。
兩種代理對(duì)比
JDK動(dòng)態(tài)代理:
代理類(lèi)與委托類(lèi)實(shí)現(xiàn)同一接口,主要是通過(guò)代理類(lèi)實(shí)現(xiàn)InvocationHandler并重寫(xiě)invoke方法來(lái)進(jìn)行動(dòng)態(tài)代理的,在invoke方法中將對(duì)方法進(jìn)行增強(qiáng)處理 優(yōu)點(diǎn):不需要硬編碼接口,代碼復(fù)用率高,缺點(diǎn):只能夠代理實(shí)現(xiàn)了接口的委托類(lèi)
CGLIB動(dòng)態(tài)代理:
代理類(lèi)將委托類(lèi)作為自己的父類(lèi)并為其中的非final委托方法創(chuàng)建兩個(gè)方法,一個(gè)是與委托方法簽名相同的方法,它在方法中會(huì)通過(guò)super調(diào)用委托方法;另一個(gè)是代理類(lèi)獨(dú)有的方法。在代理方法中,它會(huì)判斷是否存在實(shí)現(xiàn)了MethodInterceptor接口的對(duì)象,若存在則將調(diào)用intercept方法對(duì)委托方法進(jìn)行代理 優(yōu)點(diǎn):可以在運(yùn)行時(shí)對(duì)類(lèi)或者是接口進(jìn)行增強(qiáng)操作,且委托類(lèi)無(wú)需實(shí)現(xiàn)接口,缺點(diǎn):不能對(duì)final類(lèi)以及final方法進(jìn)行代理
到此,相信大家對(duì)“Spring中AOP的概念和JDK動(dòng)態(tài)代理的實(shí)現(xiàn)方式”有了更深的了解,不妨來(lái)實(shí)際操作一番吧!這里是創(chuàng)新互聯(lián)網(wǎng)站,更多相關(guān)內(nèi)容可以進(jìn)入相關(guān)頻道進(jìn)行查詢,關(guān)注我們,繼續(xù)學(xué)習(xí)!