在之前Java代理模式中大致的分析了下代理模式的类型及对每种代理类型简单的举例了下。在上篇JDK动态代理实现原理详细分析中,对其JDK代理的流程做了一个详细的分析。而本文,将介绍另一种动态代理模式:cglib动态代理。阅读完本文,你将对cglib代理模式的运行的流程有一个清晰的认识。
本文的目录如下:
目录
一:cglib动态代理的样例展示
public class MyCglib implements MethodInterceptor {
public Object getInstance(Object object){
//创建增强类
Enhancer enhancer = new Enhancer();
//设置生成的代理类的父类为传入的对象类
enhancer.setSuperclass(object.getClass());
//设置方法的拦截回调为当前对象(方法拦截的时候会调用intercept方法)
enhancer.setCallback(this);
//返回创建的动态代理对象(Enhancer有静态方法create可以直接调用)
return enhancer.create();
}
/**
* @param subProxy 生成的代理对象 该类是目标类的子类
* @param method 原目标方法
* @param objects 方法的参数
* @param methodProxy 生成的代理方法
*/
public Object intercept(Object subProxy, Method method, Object[] objects, MethodProxy methodProxy) throws Throwable {
//这里执行的逻辑将在下文详细分析
return methodProxy.invokeSuper(subProxy,objects);
}
}
目标类:
public class ZhangSan {
public String say(){
return "说中文";
}
}
测试类:
public class CglibTest {
public static void main(String[] args) throws IOException {
ZhangSan instance = (ZhangSan) new MyCglib().getInstance(new ZhangSan());
instance.say();
}
static{
//用于生成cglib字节码文件,用于下文分析,生成文件的保存路径为:D:\Tools\Study
System.setProperty(DebuggingClassWriter.DEBUG_LOCATION_PROPERTY, "D:\\Tools\\Study");
}
}
在测试类中,有一个cglib生成的代理对象instance,代理对象调用了say方法,而最终执行的却是目标类的say方法。要想弄清这个问题,我们看看生成的代理对象instance到底是什么结构。
二:cglib生成的代理类的分析
通过System.setProperty(DebuggingClassWriter.DEBUG_LOCATION_PROPERTY, "D:\\Tools\\Study"),我们可以在对应的目录下生成代理类的class文件。class文件反编译之后的结果为:
public class ZhangSan$$EnhancerByCGLIB$$c4d2de63 extends ZhangSan implements Factory
{
private boolean CGLIB$BOUND;
public static Object CGLIB$FACTORY_DATA;
private static final ThreadLocal CGLIB$THREAD_CALLBACKS;
private static final Callback[] CGLIB$STATIC_CALLBACKS;
private MethodInterceptor CGLIB$CALLBACK_0;
private static Object CGLIB$CALLBACK_FILTER;