代理详解(cglib动态代理与jdk动态代理比较)

类型 机制 回调方式 使用场景 效率
jdk动态代理 代理类和目标类都实现了同样的接口,InvocationHandler持有目标类,代理类委托InvocationHandler去调用目标类的原始方法 反射 目标类是接口类,适用于需重复创建对象(非单例) 效率瓶颈在反射调用稍慢,创建类速度快
cglib动态代理 继承机制,代理类继承了目标类并重写了目标方法,通过回调函数MethodInterceptor调用父类方法执行原始逻辑 通过FastClass方法索引调用 可以是接口也可以是具体类,非final类,非final方法。适用于无需重复创建对象(单例) 第一次调用因为要生成多个Class对象较JDK方式慢(创建类慢),多次调用因为有方法索引较反射方式快,如果方法过多switch case过多其效率会降低

上篇文章讲了两种cglib实现方式,在相同的情况下invokeSuper + setSuperClass 永远比 invoke + setInterfaces慢,因为invokeSuper + setSuperClass方式生成的FastClass类更大,switch case 更多

cglib invoke + setInterfaces 在方法数量较少的时候,在函数平均调用的情况下 比jdkProxy快,随着函数增多,优势越来越不明显,到达某个数量级一定比jdk动态代理慢,因为毕竟jdkProxy是反射调用

cglib invoke + setInterfaces 在调用特定函数(在switch中靠后的case) 会比jdk动态代理慢

贴两篇两者性能比较的文章

Cglib 与 JDK动态代理的运行性能比较

Spring AOP中的JDK和CGLib动态代理哪个效率更高?

结论:

从 jdk6 到 jdk7、jdk8 ,动态代理的性能得到了显著的提升,而 cglib 的表现并未跟上,甚至可能会略微下降。传言的 cglib 比 jdk动态代理高出 10 倍的情况也许是出现在更低版本的 jdk 上吧。

最终的测试结果大致是这样的,在1.6和1.7的时候,JDK动态代理的速度要比CGLib动态代理的速度要慢,但是并没有教科书上的10倍差距,在JDK1.8的时候,JDK动态代理的速度已经比CGLib动态代理的速度快很多了,希望小伙伴在遇到这个问题的时候能够有的放矢!

我们的关注点更应该是:应用场景的不同

你可能感兴趣的:(代理模式,jdk动态代理,cglib动态代理)