面试必考之Java的cglib和jdk动态代理对比
1、作用范围
jdk:适用于实现接口的类。主要面向接口。
cglib:通过继承类的方式来实现,该类应该为非final类型。
2、技术实现
jdk:实现InvocationHandler横切+反射
cglib:实现MethodInterceptor
接口。通过修改class文件字节码来对方法进行增强。
3、各jdk版本性能
1.6,1.7: cglib 优于 jdk
1.8: jdk 优于 cglib
为什么?
cglib通过fastclass来创建类,避免使用反射。
4、技术实现
这里需要提到字节码和class类的相互生成。
a. 字节码->class类:classloader
b. class类->字节码增强:字节码框架asm,Javassist。对应类分别是:classwriterhe 和 classpool。
5、ASM介绍
ASM 是一个 Java 字节码操控框架。它能够以二进制形式修改已有类或者动态生成类。ASM 可以直接产生二进制 class 文件,也可以在类被加载入 Java 虚拟机之前动态改变类行为。ASM 从类文件中读入信息后,能够改变类行为,分析类信息,甚至能够根据用户要求生成新类。
说明:asm操作的是jvm汇编指令。
6、Javassist介绍
Javassist是一个开源的分析、编辑和创建Java字节码的类库。通过使用Javassist对字节码操作为JBoss实现动态AOP框架。javassist是jboss的一个子项目,其主要的优点,在于简单,而且快速。直接使用java编码的形式,而不需要了解虚拟机指令,就能动态改变类的结构,或者动态生成类。
7、jdk和cglib比较
JDK动态代理主要涉及java.lang.reflect包下边的两个类:Proxy和InvocationHandler。其中,InvocationHandler是一个接口,可以通过实现该接口定义横切逻辑,并通过反射机制调用目标类的代码,动态地将横切逻辑和业务逻辑贬值在一起。
1)代理模式组成
subject:实体对象(接口)
realsubject:真正实体对象(接口实现)
proxy:代理对象(负责将请求转发到real)
2)静态代理和动态代理
静态代理:直接在代理类中调用real类。比较固化。
动态代理:在动态执行类或方法前后进行所需操作。这些操作交由Invocation Handler处理。
3)调用方式
jdk:动态通过proxy调用real。
cglib:动态通过proxy隐式继承real类。
4)jdk动态创建机制
a.获取 RealSubject上的所有接口列表;
b.确定要生成的代理类的类名,默认为:com.sun.proxy.$ProxyXXXX ;
c.根据需要实现的接口信息,在代码中动态创建 该Proxy类的字节码;
d.将对应的字节码转换为对应的class 对象;
e.创建InvocationHandler 实例handler,用来处理Proxy所有方法调用;
f.Proxy 的class对象 以创建的handler对象为参数,实例化一个proxy对象
5)cglib动态创建机制
a.查找类上的所有非final 的public类型的方法定义;
b.将这些方法的定义转换成字节码;
c.将组成的字节码转换成相应的代理的class对象;
d.实现 MethodInterceptor接口,用来处理 对代理类上所有方法的请求(这个接口和JDK动态代理InvocationHandler的功能和角色是一样的)
huan yhuanhuahuhhttps://mp.weixin.qq.com/s/BWnhRCQLCRa7e_FIL7ofqA