cglib和jdk自带的动态代理
记得上次的动态代理,感觉讲的不是很好,因为我漏了好几个重要的点。而且关于cglib这个基于asm框架的代理也没讲到。求知切记不要一知半解。
从上次的动态代理展开,为什么我们原本jdk自带了动态代理,偏偏又出来个cglib这个额外第三方库呢?人家总不可能是傻子吧,造了的轮子再造一遍。说明自带的动态代理有不足点:
委托类必须实现接口(拿上次的例子来说就是学生是委托类,DynamicProxy是代理类)
现实的开发中不可能所有的类都实现接口吧(好吧虽然这是一个面向接口、面向配置文件编程语言),所以出现了cglib这个与众不同的轮子,它不是基于反射机制,它是基于asm这个直接能够修改字节码的框架。我们只要知道一点那就是基于jdk的动态代理他的代理类实际上是实现与它相同的接口,这就意味着你不实现接口jdk的动态代理是无法为您提供服务的
cglib
填完上次的坑,我们来简单看下cglib。我们直接上例子吧
我们如上次那样先定义一个不实现Person接口的类Teacher
public class Teacher{
public void eat() {
System.out.println("teacher is eating dinner");
}
public void drink() {
System.out.println("teacher is drinking juice");
}
public void sleep() {
System.out.println("teacher is sleeping");
}
public void WC() {
System.out.println("teacher is WCing");
}
}
再是一个方法拦截器类
import java.lang.reflect.Method;
import net.sf.cglib.proxy.MethodInterceptor;
import net.sf.cglib.proxy.MethodProxy;
public class TeacherInterceptor implements MethodInterceptor {
public Object intercept(Object obj, Method method, Object[] args, MethodProxy proxy) throws Throwable {
System.out.println("----starting!----");
Object object = proxy.invokeSuper(obj, args);//调用委托类的原方法
System.out.println("----ending!----");
return object;
}
}
最后的最后是测试类
import net.sf.cglib.proxy.Enhancer;
public class TestCglib {
public static void main(String[] args) {
Enhancer enhancer = new Enhancer();
enhancer.setSuperclass(Teacher.class);
enhancer.setCallback(new TeacherInterceptor());
Teacher t = (Teacher)enhancer.create();
t.drink();
}
}
具体背后怎么实现其实是一种基于索引的方式调用委托类的具体看狼哥的分析