真实的国产乱ⅩXXX66竹夫人,五月香六月婷婷激情综合,亚洲日本VA一区二区三区,亚洲精品一区二区三区麻豆

成都創(chuàng)新互聯(lián)網(wǎng)站制作重慶分公司

Spring中AOP的概念和JDK動(dòng)態(tài)代理的實(shí)現(xiàn)方式

本篇內(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é)果:

Spring中AOP的概念和JDK動(dòng)態(tài)代理的實(shí)現(xiàn)方式

到這個(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> valuesMap = map.get(cacheKey);
 if (valuesMap == null) {
 ConcurrentMap> oldValuesMap
 = map.putIfAbsent(cacheKey,
   valuesMap = new ConcurrentHashMap<>());
 if (oldValuesMap != null) {
 valuesMap = oldValuesMap;
 }
 }

 // create subKey and retrieve the possible Supplier stored by that
 // subKey from valuesMap
 Object subKey = Objects.requireNonNull(subKeyFactory.apply(key, parameter));
 Supplier supplier = valuesMap.get(subKey);
 Factory factory = null;

 while (true) {
 if (supplier != null) {
 // supplier might be a Factory or a CacheValue instance
 V value = supplier.get();
 if (value != null) {
  return value;
 }
 }
 // else no supplier in cache
 // or a supplier that returned null (could be a cleared CacheValue
 // or a Factory that wasn't successful in installing the CacheValue)

 // lazily construct a Factory
 if (factory == null) {
 factory = new Factory(key, parameter, subKey, valuesMap);
 }

 if (supplier == null) {
 supplier = valuesMap.putIfAbsent(subKey, factory);
 if (supplier == null) {
  // successfully installed Factory
  supplier = factory;
 }
 // else retry with winning supplier
 } else {
 if (valuesMap.replace(subKey, supplier, factory)) {
  // successfully replaced
  // cleared CacheEntry / unsuccessful Factory
  // with our Factory
  supplier = factory;
 } else {
  // retry with current supplier
  supplier = valuesMap.get(subKey);
 }
 }
 }
 }

可以看到函數(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
 Supplier supplier = 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(BiFunction subKeyFactory,
  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文件反編譯查看:

Spring中AOP的概念和JDK動(dòng)態(tài)代理的實(shí)現(xiàn)方式

具體動(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é)果:

Spring中AOP的概念和JDK動(dòng)態(tài)代理的實(shí)現(xiàn)方式 

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í)!


文章題目:Spring中AOP的概念和JDK動(dòng)態(tài)代理的實(shí)現(xiàn)方式
瀏覽路徑:http://weahome.cn/article/gdpdjs.html

其他資訊

在線咨詢

微信咨詢

電話咨詢

028-86922220(工作日)

18980820575(7×24)

提交需求

返回頂部