CGLIB
CGLIB是一个功能强大,高性能的代码生成包。它为没有实现接口的类提供代理,为JDK的动态代理提供了很好的补充。
原理
CGLIB原理:动态生成一个要代理类的子类,子类重写要代理的类的所有不是final的方法。在子类中采用方法拦截的技术拦截所有父类方法的调用,顺势织入横切逻辑。它比使用java反射的JDK动态代理要快。
CGLIB底层:使用字节码处理框架ASM,来转换字节码并生成新的类。不鼓励直接使用ASM,因为它要求你必须对JVM内部结构包括class文件的格式和指令集都很熟悉。
CGLIB缺点:对于final方法,无法进行代理。
使用CGLib实现动态代理,完全不受代理类必须实现接口的限制,而且CGLib底层采用ASM字节码生成框架,使用字节码技术生成代理类,比使用Java反射效率要高。唯一需要注意的是,CGLib不能对声明为final的方法进行代理,因为CGLib原理是动态生成被代理类的子类。
实现
一:代理类
/**
* 代理类
*
* @author wangmaoyu
* @create 2018-02-26 0:58
**/
public class TargetObject{
public String mehtod1(String s){
return s;
}
public String mehtod2(String s){
return s;
}
public String mehtod3(String s){
return s;
}
}
二:代理对象拦截器
/**
* 代理对象拦截器
*
* @author wangmaoyu
* @create 2018-02-26 1:00
**/
public class TargetObjectInterceptor implements MethodInterceptor {
/**
*
* @param obj 代理对象
* @param method 委托方法
* @param objects 方法参数
* @param methodProxy 代理方法的MethodProxy对象
* @return
* @throws Throwable
*/
@Override
public Object intercept(Object obj, Method method, Object[] objects, MethodProxy methodProxy) throws Throwable {
System.out.println("调用前");
Object result=methodProxy.invokeSuper(obj,objects);
System.out.println("调用后"+result);
return result;
}
public static void main(String[] args) {
Enhancer enhancer=new Enhancer();
enhancer.setSuperclass(TargetObject.class);
enhancer.setCallback(new TargetObjectInterceptor());
TargetObject proxy= (TargetObject) enhancer.create();
System.out.println(proxy.mehtod1("我是方法1"));
System.out.println(proxy.mehtod2("我是方法2"));
System.out.println(proxy.mehtod3("我是方法3"));
}
}
效果:
调用前
调用后我是方法1
我是方法1
调用前
调用后我是方法2
我是方法2
调用前
调用后我是方法3
我是方法3
CGLIB是一个强大的高性能的代码生成库。作为JDK动态代理的互补,它对于那些没有实现接口的类提供了代理方案。在底层,它使用ASM字节码操纵框架。本质上来说,CGLIB通过产生子类覆盖非final方法来进行代理。它比使用Java反射的JDK动态代理方法更快。CGLIB不能代理一个final类或者final方法。通常来说,你可以使用JDK动态代理方法来创建代理,对于没有接口的情况或者性能因素,CGLIB是一个很好的选择。