什么是JDK动态代理和CGLIB的区别?什么是JDK动态代理和CGLIB的区别?(What is t

2019-05-14 08:24发布

在的情况下, 代理设计模式 ,是有什么区别JDK的动态代理和第三方动态代码生成API会如CGLIB ?

什么是同时使用方法和当一个人应该更喜欢一个比另一个区别?

Answer 1:

JDK动态代理只能通过接口代理(所以你的目标类必须实现一个接口,然后也由代理类实现)。

CGLIB(和了Javassist)可以创建子类的代理。 在这种情况下,代理成为目标类的子类。 无需接口。

所以Java动态代理可以代理: public class Foo implements iFoo其中CGLIB可以代理: public class Foo

编辑:

我应该指出,由于Javassist和CGLIB由子类使用代理,这是使用依赖于这个框架的时候,你不能宣布最终的方法或使课堂最后的原因。 这将允许从子类的类并重写你的方法阻止这些库。



Answer 2:

在功能上的差异

  • 在JDK代理允许实现任何一组接口,同时继承java.lang.reflect.Proxy 。 任何界面的方法,加上Object::hashCodeObject::equalsObject::toString然后被转发到InvocationHandler

  • CGLIB可以让你实现任何一组接口,同时继承任何非最后一类。 此外,方法可以选择性覆盖,即不是所有的非抽象方法必须加以拦截。 此外,也有实现的方法不同的方式。 它还提供了一个InvocationHandler类(在不同的包),但它也允许使用更先进的拦截器,例如一个调用超级方法MethodInterceptor 。 此外,CGLIB可以改善由专门拦截般的表现FixedValue 。 我曾经写过的CGLIB不同拦截器的总结 。

性能差异

JDK代理来实现,而天真地只用一个拦截调度,在InvocationHandler 。 这需要一个虚拟的方法派遣不能总是被内联的实现。 CGLIB允许创建专门的字节码是什么,有时可以提高性能。 这是实现与18种存根方法的接口一些比较:

            cglib                   JDK proxy
creation    804.000     (1.899)     973.650     (1.624)
invocation    0.002     (0.000)       0.005     (0.000)

时间以在括号标准偏差纳秒指出。 你可以找到在基准详情字节好友的教程 ,这里字节Buddy是一个更现代的替代CGLIB。 另外,请注意CGLIB不再正在积极发展。



Answer 3:

动态代理:使用JDK反射API在运行时动态的接口实现。

例如:Spring使用动态代理交易如下:

生成的代理来对bean的顶部。 它增加了跨国行为的bean。 在这里,代理使用JDK反射API在运行时动态地生成。

当应用程序停止时,代理将被销毁,我们只会有接口和bean的文件系统上。


在上面的例子中,我们有接口。 但在大多数实现的接口是不是最好的。 所以豆没有实现一个接口,在这种情况下,我们使用继承:

为了产生这样的代理,Spring使用CGLIB称为第三方库。

CGLIB(C ODEģeneration 郭宝宏)是建立在顶部ASM ,这是主要用于延伸豆的生成代理和在代理方法增加豆的行为。

对于JDK动态代理和CGLIB例子

春天REF



Answer 4:

从春天文档 :

Spring AOP的使用JDK动态代理或者CGLIB来创建一个给定的目标对象中的代理。 (JDK的动态代理首选,只要你有一个选择)。

如果被代理目标对象实现的至少一个接口然后JDK动态代理将被使用。 所有该目标类型实现的接口都将被代理。 如果目标对象没有实现任何接口,则CGLIB代理将被创建。

如果要强制使用CGLIB代理,(例如,代理目标对象,而不只是实现自接口中定义的每个方法),你可以这样做。 然而,也有一些问题需要考虑:

最后的方法不能被通知,因为它们不能被覆盖。

你需要将你的类路径里有CGLIB 2二进制文件,而使用动态代理的与JDK。 当需要CGLIB和CGLIB库类不是在类路径中,Spring将自动发出警告。

代理对象的构造器会被调用两次。 这是由于在每个代理对象中产生一个子类的CGLIB代理模型的自然结果。 对于每一个代理实例会生成两个对象:实际代理对象,并且实现了通知的子类的实例。 使用JDK代理时,此行为不是展出。 通常情况下,调用代理类型的构造器两次,是不是一个问题,因为通常只有发生分配,也没有真正的逻辑是在构造函数中实现。



文章来源: What is the difference between JDK dynamic proxy and CGLib?