CGLIB动态代理
JDK的动态代理必须提供接口才能使用,但是一些情况下是没有接口的,只能采用第三方技术了,比如CGLIB动态代理。它的优势在于不需要提供接口,只要一个非抽象类即可实现动态代理。
什么是CGLIB
CGLIB是一个功能强大,高性能的代码生成包。它为没有实现接口的类提供代理,为JDK的动态代理提供了很好的补充。通常可以使用Java的动态代理创建代理,但当要代理的类没有实现接口或者为了更好的性能,CGLIB是一个好的选择。
原理
动态生成一个要代理类的子类,子类重写要代理的类的所有不是final的方法。在子类中采用方法拦截的技术拦截所有父类方法的调用,顺势织入横切逻辑。它比使用java反射的JDK动态代理要快。使用字节码处理框架ASM,来转换字节码并生成新的类。不鼓励直接使用ASM,因为它要求你必须对JVM内部结构包括class文件的格式和指令集都很熟悉。
被代理的类
class Person{
public void goHome(String name , String fromAddress,String toAddress){
System.out.println(name + "从"+fromAddress+"去"+toAddress);
}
}
拦截器
import net.sf.cglib.proxy.Enhancer;
import net.sf.cglib.proxy.MethodInterceptor;
import net.sf.cglib.proxy.MethodProxy;
import java.lang.reflect.Method;
import java.util.Arrays;
public class CGLIBProxy implements MethodInterceptor {
//重写拦截方法
//object 目标对象
//method 目标方法
//objects 参数
//methodProxy CGLib方法代理对象
@Override
public Object intercept(Object o, Method method, Object[] objects, MethodProxy methodProxy) throws Throwable {
if (method.getName().equals("goHome")){
System.out.println(Arrays.toString(objects));
return methodProxy.invokeSuper(o,objects) ;
}
return null ;
}
public static void main(String[] args) {
//字节码增强器
Enhancer enhancer = new Enhancer() ;
enhancer.setSuperclass(Person.class);
enhancer.setCallback(new CGLIBProxy());
Person person = (Person) enhancer.create();
person.goHome("我","上海","北京");
}
}
[我, 上海, 北京]
我从上海去北京
未完待续!!!
参考:https://blog.csdn.net/zghwaicsdn/article/details/50957474