1.JDK动态代理是实现了被代理对象的接口,Cglib是继承了被代理对象。
2.JDK和Cglib都是在运行期生成字节码,JDK是直接写Class字节码,Cglib使用ASM框架写Class字节码,Cglib代理实现更复杂,生成代理类比JDK效率低。
3.JDK调用代理方法,是通过反射机制调用,Cglib是通过FastClass机制直接调用方法。
CGLIB动态代理:
使用JDK的Proxy实现代理,要求目标类与代理类实现相同的接口。若目标类不存在接口,则无法使用该方式实现。
但对于无接口的类,要为其创建动态代理类,就要使用CGLIB来实现。CGLIB代理的生成原理是生成目标类的子类,而子类是增强过的,这个子类对象就是代理对象。所以,使用CGLIB生成动态代理,要求目标类必须能够被继承,即不能是final的类。
CGLIB(Code Generation Library)是一个开源项目,是一个强大的、高性能的、高质量的代码生成类库。它可以在运行期扩展喝增强Java类。Hibernate用它来实现持久对象的字节码的动态生成,Spring用它来实现AOP编程。
CGLIB包的底层是通过使用一个小而快的字节码处理框架ASM(Java字节码操控框架)来转换字节码并生成新的类。CGLIB是通过对字节码进行增强来生成代理的。
代理实现与解析:
使用CGLIB创建代理步骤:
步骤1:导入CGLIB的Jar包:cglib-full.jar。
步骤2:定义目标类。注意不用实现任何接口。
public class AccountService {
//目标方法
public void transfer(){
System.out.println("调用Dao层,完成转账主业务。");
}
//目标方法
public void getBalance(){
System.out.println("调用Dao层,完成查询余额主业务。");
}
//该方法不能被子类覆盖,Cglib是无法代理final修饰的方法的
final public void others() {
System.out.println("调用Dao层,完成其它主业务。");
}
}
步骤3:创建代理类的工厂。该类要实现MethodInterceptor接口。
import java.lang.reflect.Method;
import net.sf.cglib.proxy.Enhancer;
import net.sf.cglib.proxy.MethodInte