JDK 动态代理只能按接口进行代理(因此您的目标类需要实现一个接口,然后该接口也由代理类实现)。
CGLIB(和javassist)可以通过子类化来创建代理。在这种情况下,代理成为目标类的子类。无需接口。
因此,Java Dynamic代理可以代理:CGLIB可以代理:public class Foo implements iFoo
public class Foo
编辑:
我应该提到,因为javassist和CGLIB通过子类化使用代理,这就是为什么在使用依赖于它的框架时,你不能声明最终方法或使类最终的原因。这将阻止这些库允许对类进行子类化并重写方法。
功能差异
JDK 代理允许在子类化时实现任何一组接口。任何接口方法,加上,然后转发到
调用处理程序
。此外,还实现了标准库接口。Object
Object::hashCode
Object::equals
Object::toString
java.lang.reflect.Proxy
cglib 允许您实现任何一组接口,同时对任何非最终类进行子类化。此外,方法可以选择性地重写,即并非所有非抽象方法都需要被拦截。此外,还有实现方法的不同方法。它还提供了一个类(在不同的包中),但它也允许通过使用更高级的拦截器来调用超级方法,例如.此外,cglib 可以通过专门的拦截来提高性能,例如 .我曾经为cglib写过不同拦截器的摘要。
InvocationHandler
MethodInterceptor
FixedValue
性能差异
JDK 代理的实现相当天真,只有一个拦截调度程序,即 .这需要将虚拟方法调度到不能总是内联的实现。Cglib允许创建专门的字节码,有时可以提高性能。以下是使用 18 个存根方法实现接口的一些比较:InvocationHandler
cglib JDK proxy
creation 804.000 (1.899) 973.650 (1.624)
invocation 0.002 (0.000) 0.005 (0.000)
时间以纳秒为单位,标准偏差以大括号为单位。您可以在Byte Buddy的教程中找到有关基准测试的更多详细信息,其中Byte Buddy是cglib的更现代的替代方案。另外,请注意,cglib不再处于积极开发状态。
-
使用批注修改方法 如何更改方法在 Java 中执行的操作? 我的意思是,我正在尝试使用注释来制作以下代码 我发现了一些关于Java Reflection的东西,但我还没有找到任何资源来帮助我完成我正在做的事情。 显然
-
-
-
如何使用反射定义动态设定器和获取器? 我有一个字符串列表,字段名称,从资源包循环中的类。我创建一个对象,然后使用循环,我想为该对象设置值。例如,对于对象 对于getter来说也是如此。我知道反思会有所帮助,但我无法做
-
如何防止通过反射进入? 在Java文档中,它提到使用方法我们可以违反封装的原则。 但是,如果我正在编写任何具有完全安全性的类,例如使用私有变量,我该如何防止通过反射访问它? 例如,我有一个具有完整安全