在我的上一篇博客<jdk 动态代理 模拟>中已经详细的说过了JDK自带的动态代理.JDK的动态代理机制只能代理实现了接口的类,而不能实现接口的类就不能实现JDK的动态代理,cglib是针对类来实现代理的,他的原理是对指定的目标类生成一个子类,并覆盖其中方法实现增强,但因为采用的是继承,所以不能对final修饰的类进行代理。
Cglib是一个优秀的动态代理框架,它的底层使用ASM在内存中动态的生成被代理类的子类。使用CGLIB即使被代理类没有实现任何接口也可以实现动态代理功能。
使用CGLIB需要导入以下两个jar文件:
asm.jar – CGLIB的底层实现。
cglib.jar – CGLIB的核心jar包。
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);//虽然第一个参数是被代理对象,也不会出现死循环的问题。
具体代码:
代理类:
/**
* 使用cglib动态代理
* @author wanwan
*
*/
public class cglibdynamicProxy implements MethodInterceptor {
private Object target;
/**
* 创建代理对象
* @param target
* @return
*/
public Object getInstance(Object target){
this.target=target;
Enhancer enhancer=new Enhancer();
enhancer.setSuperclass(this.target.getClass());
//回调方法
enhancer.setCallback(this);
//创建代理对象
return enhancer.create();
}
//回调方法
@Override
public Object intercept(Object object, Method method, Object[] args,
MethodProxy proxy) throws Throwable {
System.out.println("-----start-----");
proxy.invokeSuper(object, args);
System.out.println("-----end-----");
return null;
}
}
不实现接口的被代理类
/**
* 没有实现接口的类
* @author wanwan
*
*/
public class UserServiceImpl {
public void add(){
System.out.println("---add---");
}
}
Cglib的类图:
在java中最常用的是使用JDK自带的动态代理,这时候就需要实现接口.JDK的动态代理是实现针对接口编程的,如果在缺少接口的情况下,就可以考虑使用Cglib动态代理.