溫馨提示×

溫馨提示×

您好,登錄后才能下訂單哦!

密碼登錄×
登錄注冊×
其他方式登錄
點擊 登錄注冊 即表示同意《億速云用戶服務條款》

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

發(fā)布時間:2021-09-06 17:00:01 來源:億速云 閱讀:132 作者:chen 欄目:編程語言

本篇內(nèi)容主要講解“Spring中AOP的概念和JDK動態(tài)代理的實現(xiàn)方式”,感興趣的朋友不妨來看看。本文介紹的方法操作簡單快捷,實用性強。下面就讓小編來帶大家學習“Spring中AOP的概念和JDK動態(tài)代理的實現(xiàn)方式”吧!

AOP的概念

AOP:Aspect-Oriented Programming(面向切面編程),維基百科的解釋如下:Aspect是一種新的模塊化機制,用來描述分散在對象、類或者函數(shù)中的橫切關注點,從關注點中分離出橫切關注點是面向切面的程序設計的核心概念。分離關注點使解決特定領域問題的代碼從業(yè)務邏輯中獨立出來,業(yè)務邏輯的代碼中不在含有針對特定領域問題的代碼的調(diào)用,業(yè)務邏輯同特定領域問題的關系通過切面來封裝、維護,這樣原本分散在整個應用程序中的變動就可以很好地管理起來。從AOP的角度,應用可以分為橫切關注點和業(yè)務邏輯代碼,實際開發(fā)中,這些橫切關注點往往會直接嵌入到業(yè)務邏輯代碼中,面向切面編程就是要解決把橫切關注點與業(yè)務邏輯相分離

實現(xiàn)方式:

Spring默認使用 JDK 動態(tài)代理作為AOP的代理,缺陷是目標類的類必須實現(xiàn)接口,否則不能使用JDK動態(tài)代理。如果需要代理的是類而不是接口,那么Spring會默認使用CGLIB代理,關于兩者的區(qū)別:jdk動態(tài)代理是通過java的反射機制來實現(xiàn)的,目標類必須要實現(xiàn)接口,cglib是針對類來實現(xiàn)代理的,他的原理是動態(tài)的為指定的目標類生成一個子類,并覆蓋其中方法實現(xiàn)增強,但因為采用的是繼承,所以不能對final修飾的類進行代理。

JDK動態(tài)代理

Jdk動態(tài)代理是在程序運行過程中,根據(jù)目標類實現(xiàn)的接口來動態(tài)生成代理類的class文件,使用主要涉及兩個類:

InvocationHandler接口: 它提供了一個invoke(Object obj,Method method, Object[] args)方法供實現(xiàn)者提供相應的代理邏輯的實現(xiàn)。可以對實際的實現(xiàn)進行一些特殊的處理其中參數(shù)

            Object obj :被代理的目標類

            Method method: 需要執(zhí)行的目標類的方法

            Object[] args :目標方法的參數(shù)

Proxy類:提供一個方法newProxyInstance (ClassLoader loader, Class[] interfaces, InvocationHandler h)來獲得動態(tà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(), //通過這個ClassLoader生成代理對象
 targetClass.getClass().getInterfaces(),//代理類已實現(xiàn)的接口
 this); //動態(tài)代理調(diào)用方法是關聯(lián)的InvocationHandler,最終通過此InvocationHandler的invoke方法執(zhí)行真正的方法
 }
 
 //實現(xiàn)相應的代理邏輯
 @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;
 }
}

測試類:

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();
 }
}

運行結果:

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

到這個其實還是有點困惑,Proxy.newProxyInstance()這個返回的是什么? Invoke方法在哪里調(diào)用的?我們看一下JDK源碼:看看DK動態(tài)代理的過程是什么樣的:

根據(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<Object, Supplier<V>> valuesMap = map.get(cacheKey);
 if (valuesMap == null) {
 ConcurrentMap<Object, Supplier<V>> oldValuesMap
 = map.putIfAbsent(cacheKey,
   valuesMap = new ConcurrentHashMap<>());
 if (oldValuesMap != null) {
 valuesMap = oldValuesMap;
 }
 }

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

 while (true) {
 if (supplier != null) {
 // supplier might be a Factory or a CacheValue<V> 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,實際上是一個Factory對象,那么繼續(xù)查看Factory.get()方法

public synchronized V get() { // serialize access
 // re-check
 Supplier<V> 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<V> 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;那么直接查看賦值語句: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 loader, Class<?>[] interfaces) {

 Map<Class<?>, 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());
 }
 }
}

直接畫重點:

byte[] proxyClassFile = ProxyGenerator.generateProxyClass(
 proxyName, interfaces, accessFlags);
return defineClass0(loader, proxyName,
   proxyClassFile, 0, proxyClassFile.length);

調(diào)用ProxyGenerator.generateProxyClass最終動態(tài)生成一個代理類,但是似乎并未找到何處調(diào)用了invoke方法;參考CSDN: https://www.jb51.net/article/118935.htm這篇文章,嘗試將這個動態(tài)生成的二進制字節(jié)碼輸出到本地,并反編譯出來一看究竟,測試代碼如下:

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();
 //輸出動態(tà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工具將這個二進制class文件反編譯查看:

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

具體動態(tà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());
 }
 }

終于看到關于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);
 }
 }

實際上動態(tài)代理類繼承自Proxy,并且實現(xiàn)了目標類繼承的接口,在createOrder方法中調(diào)用了invoke方法,實現(xiàn)了切面邏輯的植入,這里也回答了一個問題,為什么JDK動態(tài)代理的目標類必須是實現(xiàn)接口的,因為代理類其實是針對接口代理,而不是針對類來代理的,動態(tài)代理類自己繼承自Proxy,Java也不允許多重繼承。動態(tài)代理類和目標類其實是各自實現(xiàn)了接口,代理類通過InvocationHandler.invoke實現(xiàn)對目標類方法的調(diào)用。

CGLIB動態(tài)代理

CGLIB代理是通過使用一個字節(jié)碼處理框架ASM,來轉換字節(jié)碼并生成新的類,并在子類中采用方法攔截的技術攔截所有父類方法的調(diào)用,實現(xiàn)織如如橫切邏輯 ,效率上比使用反射技術的JDK動態(tài)代理要高,但是由于CGLIB的原理是動態(tài)為目標類生成子類代理類,所以不能為聲明為final的方法進行代理。其使用主要涉及兩個類:

MethodInterceptor接口:該接口提供一個方法intercept(Object arg0, Method arg1, Object[] arg2, MethodProxy arg3)主要用于攔截目標類方法的調(diào)用

        Object arg0, :被代理的目標類

           Method arg1, 委托方法

        Object[] arg2, 方法參數(shù)

        MethodProxy arg3 :代理方法的MethodProxy對象

Enhancer類:用于創(chuàng)建代理類

示例:

實現(xiàn)MethodInterceptor接口,代理類在調(diào)用方法時,CGLIB會回調(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)建代理對象 
 *
 */ 
 public Object getInstance() { 
 Enhancer enhancer = new Enhancer(); 
 
 //設置目標類(需要被代理的類) 
 enhancer.setSuperclass(this.targetClass.getClass());
 
 // 回調(diào)方法 
 enhancer.setCallback(this);
 
 // 創(chuàng)建代理對象 
 return enhancer.create(); 
 } 
 
 /** 
 * 攔截所有目標類方法的調(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; 
 }
}

測試方法:

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); 
  //通過生成子類的方式創(chuàng)建代理類 
 OrderServiceImpl proxyImp = (OrderServiceImpl)proxy.getInstance();
 proxyImp.createOrder();
 }

結果:

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

System.setProperty(DebuggingClassWriter.DEBUG_LOCATION_PROPERTY, "D:\\class");將cglib動態(tà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.<init>();
  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();
 }
}

上面的代碼可以看到代理類OrderServiceImpl$$EnhancerByCGLIB$$17779aa4 繼承目標類OrderServiceImpl并且實現(xiàn)了接口Factory,代理類中關于createorder生成了兩個方法CGLIB$createOrder$0和createOrder:

CGLIB$createOrder$0方法內(nèi)部直接調(diào)用目標類的supper.createOrder

createOrder方法內(nèi)部首先盤點否實現(xiàn)了MethodInterceptor接口的callback,如果存在則調(diào)用MethodInterceptor接口攔截方法intercept,根據(jù)前面的實現(xiàn)intercept方法內(nèi)部實現(xiàn)了對目標方法的調(diào)用Object o1 = arg3.invokeSuper(arg0, arg2) ,invokeSuper內(nèi)部實際上是直接調(diào)用的代理類的CGLIB$createOrder$0()方法,最終調(diào)用了目標類createOrder。

兩種代理對比

JDK動態(tài)代理:

代理類與委托類實現(xiàn)同一接口,主要是通過代理類實現(xiàn)InvocationHandler并重寫invoke方法來進行動態(tài)代理的,在invoke方法中將對方法進行增強處理  優(yōu)點:不需要硬編碼接口,代碼復用率高,缺點:只能夠代理實現(xiàn)了接口的委托類

CGLIB動態(tài)代理:

代理類將委托類作為自己的父類并為其中的非final委托方法創(chuàng)建兩個方法,一個是與委托方法簽名相同的方法,它在方法中會通過super調(diào)用委托方法;另一個是代理類獨有的方法。在代理方法中,它會判斷是否存在實現(xiàn)了MethodInterceptor接口的對象,若存在則將調(diào)用intercept方法對委托方法進行代理  優(yōu)點:可以在運行時對類或者是接口進行增強操作,且委托類無需實現(xiàn)接口,缺點:不能對final類以及final方法進行代理

到此,相信大家對“Spring中AOP的概念和JDK動態(tài)代理的實現(xiàn)方式”有了更深的了解,不妨來實際操作一番吧!這里是億速云網(wǎng)站,更多相關內(nèi)容可以進入相關頻道進行查詢,關注我們,繼續(xù)學習!

向AI問一下細節(jié)

免責聲明:本站發(fā)布的內(nèi)容(圖片、視頻和文字)以原創(chuàng)、轉載和分享為主,文章觀點不代表本網(wǎng)站立場,如果涉及侵權請聯(lián)系站長郵箱:is@yisu.com進行舉報,并提供相關證據(jù),一經(jīng)查實,將立刻刪除涉嫌侵權內(nèi)容。

AI