序言
在动态代理的实现中,其中一个种实现就是Cglib,它可以代理所有对象的非final方法。实现原理就是通过字节码来动态生成一个代理类。
这里归纳总结下Cglib ^_^
参考资料:
- CGLIB(Code Generation Library) 介绍与原理 | 菜鸟教程
什么是 CGLIB
CGLIB是一个功能强大,高性能的代码生成包。它为没有实现接口的类提供代理(JDK的反射代理只能针对接口来代理cuiyaonan2000@163.com),为JDK的动态代理提供了很好的补充。通常可以使用Java的动态代理创建代理,但当要代理的类没有实现接口或者为了更好的性能,CGLIB是一个好的选择。
CGLIB作为一个开源项目,其代码托管在github,地址为:https://github.com/cglib/cglib
特点
- CGLIB 原理:动态生成一个要代理类的子类,子类重写要代理的类的所有不是final的方法。在子类中采用方法拦截的技术拦截所有父类方法的调用,顺势织入横切逻辑。它比使用java反射的JDK动态代理要快。
- CGLIB 底层:使用字节码处理框架ASM,来转换字节码并生成新的类。不鼓励直接使用ASM,因为它要求你必须对JVM内部结构包括class文件的格式和指令集都很熟悉。
- CGLIB缺点:对于final方法,无法进行代理。
- 但是CGLib在创建代理对象时所花费的时间却比JDK多得多,所以对于单例的对象,因为无需频繁创建对象,用CGLib合适,反之,使用JDK方式要更为合适一些。(cglib与jdk的动态代理的应用场景cuiyaonan2000@163.com)
CGLIB组成结构
CGLIB底层使用了ASM(一个短小精悍的字节码操作框架)来操作字节码生成新的类。除了CGLIB库外,脚本语言(如Groovy何BeanShell)也使用ASM生成字节码。ASM使用类似SAX的解析器来实现高性能。我们不鼓励直接使用ASM,因为它需要对Java字节码的格式足够的了解。参考如上的建议ASM不建议直接使用cuiyaonan2000@163.com
CGLIB的使用
Jar包
- cglib-nodep-2.2.jar:使用nodep包不需要关联asm的jar包,jar包内部包含asm的类.
- cglib-2.2.jar:使用此jar包需要关联asm的jar包,否则运行时报错.
CGLIB类库
由于基本代码很少,学起来有一定的困难,主要是缺少文档和示例,这也是CGLIB的一个不足之处。
本系列使用的CGLIB版本是2.2。
- net.sf.cglib.core: 底层字节码处理类,他们大部分与ASM有关系。
- net.sf.cglib.transform: 编译期或运行期类和类文件的转换
- net.sf.cglib.proxy: 实现创建代理和方法拦截器的类
- net.sf.cglib.reflect: 实现快速反射和C#风格代理的类
- net.sf.cglib.util: 集合排序等工具类
- net.sf.cglib.beans: JavaBean相关的工具类
实例
参考Java Proxy_cuiyaonan2000的博客-CSDN博客_java proxy类