设置为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倍以上