当前位置: 移动技术网 > IT编程>开发语言>Java > Spring温故而知新系列教程之AOP代理

Spring温故而知新系列教程之AOP代理

2019年07月19日  | 移动技术网IT编程  | 我要评论

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

运行结果:

到这个其实还是有点困惑,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<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);
 }
 }
 }
 }

可以看到函数return value;  而 v value = supplier.get();   继续往下读可以发现 supper=factory,实际上是一个factory对象,那么继续查看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);

调用proxygenerator.generateproxyclass最终动态生成一个代理类,但是似乎并未找到何处调用了invoke方法;参考csdn: 这篇文章,尝试将这个动态生成的二进制字节码输出到本地,并反编译出来一看究竟,测试代码如下:

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文件反编译查看:

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

结果:

 

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.<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并且实现了接口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方法进行代理

总结

以上就是这篇文章的全部内容了,希望本文的内容对大家的学习或者工作具有一定的参考学习价值,如果有疑问大家可以留言交流,谢谢大家对移动技术网的支持。

如对本文有疑问, 点击进行留言回复!!

相关文章:

验证码:
移动技术网