Java动态代理之CGLIB
概要
Cglib是一个优秀的动态代理框架,它的底层使用ASM在内存中动态的生成被代理类的子类。使用CGLIB即使被代理类没有实现任何接口也可以实现动态代理功能。CGLIB具有简单易用,它的运行速度要远远快于JDK的Proxy动态代理。
CGLIB的核心类:
net.sf.cglib.proxy.Enhancer – 主要的增强类
net.sf.cglib.proxy.MethodInterceptor – 主要的方法拦截类,它是Callback接口的子接口,需要用户实现
net.sf.cglib.proxy.MethodProxy – JDK的java.lang.reflect.Method类的代理类,可以方便的实现对源对象方法的调用,如使用:
Object o = methodProxy.invokeSuper(proxy, args);//虽然第一个参数是被代理对象,也不会出现死循环的问题。
使用实例
被代理类:
package cglib;
/*
* 要代理的目标
*/
public class Target {
public void say(String string) {
System.out.println("Target.say()");
System.out.println(string);
}
}
实现代理类:
package cglib;
import java.lang.reflect.Method;
import net.sf.cglib.proxy.MethodInterceptor;
import net.sf.cglib.proxy.MethodProxy;
public class ProxyTest implements MethodInterceptor {
@Override
/*
* (non-Javadoc)
* @see net.sf.cglib.proxy.MethodInterceptor#intercept(java.lang.Object, java.lang.reflect.Method, java.lang.Object[], net.sf.cglib.proxy.MethodProxy)
*
* 第一个参数表示调用方法来自哪个对象;
第二个参数表示调用方法的Method对象;
第三个参数表示此次调用的输入参数列表;
第四个参数MethodProxy 类型的,它应该是cglib生成用来代替Method对象的一个对象,使用MethodProxy比调用JDK自身的Method直接执行方法效率会有提升
*/
public Object intercept(Object arg0, Method arg1, Object[] arg2, MethodProxy arg3) throws Throwable {
System.out.println("bofore");
/*
* invokeSuper()方法,因为动态生成的类是子类或者是实现类,因此invokeSuper就是执行父类中方法的意思。
*/
Object object = arg3.invokeSuper(arg0, arg2);
System.out.println("after");
return "hahah";
}
}
测试类:
package cglib;
import java.lang.reflect.Method;
import net.sf.cglib.proxy.MethodInterceptor;
import net.sf.cglib.proxy.MethodProxy;
public class ProxyTest implements MethodInterceptor {
@Override
/*
* (non-Javadoc)
* @see net.sf.cglib.proxy.MethodInterceptor#intercept(java.lang.Object, java.lang.reflect.Method, java.lang.Object[], net.sf.cglib.proxy.MethodProxy)
*
* 第一个参数表示调用方法来自哪个对象;
第二个参数表示调用方法的Method对象;
第三个参数表示此次调用的输入参数列表;
第四个参数MethodProxy 类型的,它应该是cglib生成用来代替Method对象的一个对象,使用MethodProxy比调用JDK自身的Method直接执行方法效率会有提升
*/
public Object intercept(Object arg0, Method arg1, Object[] arg2, MethodProxy arg3) throws Throwable {
System.out.println("bofore");
/*
* invokeSuper()方法,因为动态生成的类是子类或者是实现类,因此invokeSuper就是执行父类中方法的意思。
*/
Object object = arg3.invokeSuper(arg0, arg2);
System.out.println("after");
return "hahah";
}
}
输出:
bofore
Target.say()
aaaa
after