我们专注攀枝花网站设计 攀枝花网站制作 攀枝花网站建设
成都网站建设公司服务热线:400-028-6601

网站建设知识

十年网站开发经验 + 多家企业客户 + 靠谱的建站团队

量身定制 + 运营维护+专业推广+无忧售后,网站问题一站解决

Spring中AOP的概念和JDK动态代理的实现方式

本篇内容主要讲解“Spring中AOP的概念和JDK动态代理的实现方式”,感兴趣的朋友不妨来看看。本文介绍的方法操作简单快捷,实用性强。下面就让小编来带大家学习“Spring中AOP的概念和JDK动态代理的实现方式”吧!

网站建设哪家好,找创新互联公司!专注于网页设计、网站建设、微信开发、小程序设计、集团企业网站建设等服务项目。为回馈新老客户创新互联还提供了兰考免费建站欢迎大家使用!

AOP的概念

AOP:Aspect-Oriented Programming(面向切面编程),维基百科的解释如下:Aspect是一种新的模块化机制,用来描述分散在对象、类或者函数中的横切关注点,从关注点中分离出横切关注点是面向切面的程序设计的核心概念。分离关注点使解决特定领域问题的代码从业务逻辑中独立出来,业务逻辑的代码中不在含有针对特定领域问题的代码的调用,业务逻辑同特定领域问题的关系通过切面来封装、维护,这样原本分散在整个应用程序中的变动就可以很好地管理起来。从AOP的角度,应用可以分为横切关注点和业务逻辑代码,实际开发中,这些横切关注点往往会直接嵌入到业务逻辑代码中,面向切面编程就是要解决把横切关注点与业务逻辑相分离

实现方式:

Spring默认使用 JDK 动态代理作为AOP的代理,缺陷是目标类的类必须实现接口,否则不能使用JDK动态代理。如果需要代理的是类而不是接口,那么Spring会默认使用CGLIB代理,关于两者的区别:jdk动态代理是通过java的反射机制来实现的,目标类必须要实现接口,cglib是针对类来实现代理的,他的原理是动态的为指定的目标类生成一个子类,并覆盖其中方法实现增强,但因为采用的是继承,所以不能对final修饰的类进行代理。

JDK动态代理

Jdk动态代理是在程序运行过程中,根据目标类实现的接口来动态生成代理类的class文件,使用主要涉及两个类:

InvocationHandler接口: 它提供了一个invoke(Object obj,Method method, Object[] args)方法供实现者提供相应的代理逻辑的实现。可以对实际的实现进行一些特殊的处理其中参数

 Object obj :被代理的目标类

 Method method: 需要执行的目标类的方法

 Object[] args :目标方法的参数

Proxy类:提供一个方法newProxyInstance (ClassLoader loader, Class[] interfaces, InvocationHandler h)来获得动态代理类

示例代码:

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(),//代理类已实现的接口
 this); //动态代理调用方法是关联的InvocationHandler,最终通过此InvocationHandler的invoke方法执行真正的方法
 }
 
 //实现相应的代理逻辑
 @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动态代理的实现方式

到这个其实还是有点困惑,Proxy.newProxyInstance()这个返回的是什么? Invoke方法在哪里调用的?我们看一下JDK源码:看看DK动态代理的过程是什么样的:

根据源码内部的函数调用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);
 }
 }
 }
 }

可以看到函数return value;  而 V value = supplier.get();   继续往下读可以发现 supper=factory,实际上是一个Factory对象,那么继续查看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;那么直接查看赋值语句: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类型对象,直接查看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());
 }
 }
}

直接画重点:

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

调用ProxyGenerator.generateProxyClass最终动态生成一个代理类,但是似乎并未找到何处调用了invoke方法;参考CSDN: https://www.jb51.net/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();
 //输出动态代理类字节码
 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动态代理的实现方式

具体动态代理类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);
 }
 }

实际上动态代理类继承自Proxy,并且实现了目标类继承的接口,在createOrder方法中调用了invoke方法,实现了切面逻辑的植入,这里也回答了一个问题,为什么JDK动态代理的目标类必须是实现接口的,因为代理类其实是针对接口代理,而不是针对类来代理的,动态代理类自己继承自Proxy,Java也不允许多重继承。动态代理类和目标类其实是各自实现了接口,代理类通过InvocationHandler.invoke实现对目标类方法的调用。

CGLIB动态代理

CGLIB代理是通过使用一个字节码处理框架ASM,来转换字节码并生成新的类,并在子类中采用方法拦截的技术拦截所有父类方法的调用,实现织如如横切逻辑 ,效率上比使用反射技术的JDK动态代理要高,但是由于CGLIB的原理是动态为目标类生成子类代理类,所以不能为声明为final的方法进行代理。其使用主要涉及两个类:

MethodInterceptor接口:该接口提供一个方法intercept(Object arg0, Method arg1, Object[] arg2, MethodProxy arg3)主要用于拦截目标类方法的调用

Object arg0, :被代理的目标类

           Method arg1, 委托方法

Object[] arg2, 方法参数

MethodProxy arg3 :代理方法的MethodProxy对象

Enhancer类:用于创建代理类

示例:

实现MethodInterceptor接口,代理类在调用方法时,CGLIB会回调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;
 }
 /** 
 * 创建代理对象 
 *
 */ 
 public Object getInstance() { 
 Enhancer enhancer = new Enhancer(); 
 
 //设置目标类(需要被代理的类) 
 enhancer.setSuperclass(this.targetClass.getClass());
 
 // 回调方法 
 enhancer.setCallback(this);
 
 // 创建代理对象 
 return enhancer.create(); 
 } 
 
 /** 
 * 拦截所有目标类方法的调用 
 *
 */
 @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); 
  //通过生成子类的方式创建代理类 
 OrderServiceImpl proxyImp = (OrderServiceImpl)proxy.getInstance();
 proxyImp.createOrder();
 }

结果:

Spring中AOP的概念和JDK动态代理的实现方式 

System.setProperty(DebuggingClassWriter.DEBUG_LOCATION_PROPERTY, "D:\\class");将cglib动态代理类输出到指定目录,反编译查看一下代理类真面目:

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

上面的代码可以看到代理类OrderServiceImpl$$EnhancerByCGLIB$$17779aa4 继承目标类OrderServiceImpl并且实现了接口Factory,代理类中关于createorder生成了两个方法CGLIB$createOrder$0和createOrder:

CGLIB$createOrder$0方法内部直接调用目标类的supper.createOrder

createOrder方法内部首先盘点否实现了MethodInterceptor接口的callback,如果存在则调用MethodInterceptor接口拦截方法intercept,根据前面的实现intercept方法内部实现了对目标方法的调用Object o1 = arg3.invokeSuper(arg0, arg2) ,invokeSuper内部实际上是直接调用的代理类的CGLIB$createOrder$0()方法,最终调用了目标类createOrder。

两种代理对比

JDK动态代理:

代理类与委托类实现同一接口,主要是通过代理类实现InvocationHandler并重写invoke方法来进行动态代理的,在invoke方法中将对方法进行增强处理  优点:不需要硬编码接口,代码复用率高,缺点:只能够代理实现了接口的委托类

CGLIB动态代理:

代理类将委托类作为自己的父类并为其中的非final委托方法创建两个方法,一个是与委托方法签名相同的方法,它在方法中会通过super调用委托方法;另一个是代理类独有的方法。在代理方法中,它会判断是否存在实现了MethodInterceptor接口的对象,若存在则将调用intercept方法对委托方法进行代理  优点:可以在运行时对类或者是接口进行增强操作,且委托类无需实现接口,缺点:不能对final类以及final方法进行代理

到此,相信大家对“Spring中AOP的概念和JDK动态代理的实现方式”有了更深的了解,不妨来实际操作一番吧!这里是创新互联网站,更多相关内容可以进入相关频道进行查询,关注我们,继续学习!


当前名称:Spring中AOP的概念和JDK动态代理的实现方式
链接分享:http://shouzuofang.com/article/gdpdjs.html

其他资讯