1、作用范围
1) JDK:适用于实现接口的类,主要面向接口。
2) CgLib:通过继承类的方式来实现,该类应该为非final类型。
2、技术实现
1) JDK:实现InvocationHandler横切+反射
2) CgLib:实现MethodInterceptor接口。通过修改class文件字节码来对方法进行增强。
3、各jdk版本性能
1) 1.6,1.7 : cglib 优于 jdk
2) 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动态创建机制
1) 获取 RealSubject上的所有接口列表;
2) 确定要生成的代理类的类名,默认为:com.sun.proxy.$ProxyXXXX ;
3) 根据需要实现的接口信息,在代码中动态创建 该Proxy类的字节码;
4) 将对应的字节码转换为对应的class 对象;
5) 创建InvocationHandler 实例handler,用来处理Proxy所有方法调用;
6) Proxy 的class对象 以创建的handler对象为参数,实例化一个proxy对象
5)cglib动态创建机制
1) 查找类上的所有非final 的public类型的方法定义;
2) 将这些方法的定义转换成字节码;
3) 将组成的字节码转换成相应的代理的class对象;
4) 实现 MethodInterceptor接口,用来处理 对代理类上所有方法的请求(这个接口和JDK动态代理InvocationHandler的功能和角色是一样的)