Spring代理比较—proxy-target-class含义

  proxy-target-class="true"/>


设置为true:启用cglib代理,设置为false:启用jdk代理(基于接口)


JDK动态代理是利用反射机制生成一个实现代理接口的匿名类,在调用具体方法前调用InvokeHandler来处理。

JDKProxy implements InvocationHandler 并实现invoke(Object proxy, Method method, Object[] args)方法

(ret = method.invoke(targetObject, args);

//生成代理对象

public Object newProxy(Object targetObject) {

return Proxy.newProxyInstance(targetObject.getClass().getClassLoader(),

targetObject.getClass().getInterfaces(), this);//返回代理对象

}

而cglib动态代理是利用asm开源包,对代理对象类的class文件加载进来,通过修改其字节码生成子类来处理。

CGLibProxy implements MethodInterceptor

并实现 intercept(Object proxy, Method method, Object[] args, MethodProxy methodProxy)方法

(ret = method.invoke(targetObject, args);

//生成代理对象

public Object createProxyObject(Object obj) {

Enhancer enhancer = new Enhancer();

enhancer.setSuperclass(obj.getClass());

enhancer.setCallback(this);

Object proxyObj = enhancer.create();

return proxyObj;// 返回代理对象

}

(1)使用CGLib实现动态代理,CGLib底层采用ASM字节码生成框架,使用字节码技术生成代理类,比使用Java反射效率要高。

   唯一需要注意的是,CGLib不能对声明为final的方法进行代理,因为CGLib原理是动态生成被代理类的子类。

CGlib在创建代理这一块没有JDK动态代理快,但是运行速度比JDK动态代理要快,可以用单例模式减少创建。

(2)在对JDK动态代理与CGlib动态代理的代码实验中看,1W次执行下,JDK7及8的动态代理性能比CGlib要好20%左右。


jdk6 下,在运行次数较少的情况下,jdk动态代理与 cglib 差距不明显,甚至更快一些;

而当调用次数增加之后, cglib 表现稍微更快一些,然而仅仅是“稍微”好一些,远没达到 10 倍差距。

jdk7 下,在运行次数较少(1,000,000)的情况下,jdk动态代理比 cglib 快了差不多30%;

而当调用次数增加之后(50,000,000), 动态代理比 cglib 快了接近1倍。

jdk8延续了jdk7

从 jdk6 到 jdk7、jdk8 ,动态代理的性能得到了显著的提升,而 cglib 的表现并未跟上,甚至可能会略微下降。


jdk6: CGLIB创建代理对象速度大概比JDK Proxy慢10倍以上,执行速度是JDK Proxy的2倍左右 

jdk7:CGLIB创建代理对象速度大概比JDK Proxy慢3倍,执行速度是JDK Proxy的3倍以上 



你可能感兴趣的:(Java后端开发)