一、概要
cglib源码看了下,总结下自己理解,小结如下:
二、通过继承目标类来实现代理
要点描述
- 代理类:继承了目标类,则在代理类中通过调用父类方法,即调用到了目标类方法。整个代理过程无需强制持有目标类的实例。
- 增强器/拦截器类:实现MethodInterceptor接口的intercept方法,以达成对目标类的代理或者说功能增强(方法参数见下文:增强器/拦截器接口源码)。
- 增强器/拦截器映射器:CallbackFilter。通过入参为Method类型,出参为int型增强器/拦截器数组的索引的accept方法,决定代理方法实际对应的是哪一个增强器/拦截器。(见下文:接口实现示例)
- 通过Enhancer类实例,可以设置继承的目标类,传入增强器/拦截器实例组(可选),及设置增强器/拦截器映射器(可选),最终调用Enhancer#create()方法创建代理实例。
- 对代理类方法的调用,实际是对增强器/拦截器组中的指定1个增强器/拦截器的intercept方法进行调用(如果没有设置增强器/拦截器,则通过super直接调用父类方法,即目标方法。不过目前还没找到能不设置的方法)
- intercept方法,一般通过代理实例上调用代理方法来反射调用到目标方法。
//1、正确:一般通过代理实例上反射调用代理方法来调用到目标方法。
Object returnVal = proxyMethod.invokeSuper(proxyObj,args);
//2、错误:在代理实例上反射调用目标方法,会递归调用到代理方法,陷入死循环,最终报错
//*** java.lang.instrument ASSERTION FAILED ***: "!errorOutstanding" with message transform method call failed at JPLISAgent.c line: 844
Object returnVal = targetMethod.invoke(proxyObj,args);
//3、错误:在代理实例上反射调用目标方法。最终报错,结果同2
Object returnVal = proxyMethod.invoke(proxyObj,args);
//4、正确:构造增强器/拦截器实例时,传入目标类实例targetObj,则可以在此通过目标类实例反射调用目标方法。