前段时间看了黑马Spring教程中,有期视频讲解Cglib动态代理。
代码如下图:
可以看到调用目标对象的方法代码为:
method.invoke(target,objects);
在其他地方看到的此处代码是:
methodProxy.invokeSuper(o,objects);
注意:两个方法传参不同。
下面演示下两者区别中的一种:
- invokeSuper
import org.springframework.cglib.proxy.Enhancer;
import org.springframework.cglib.proxy.MethodInterceptor;
import org.springframework.cglib.proxy.MethodProxy;
import java.lang.reflect.Method;
public class CglibProxyTest {
public static void main(String[] args) {
Enhancer enhancer = new Enhancer();
Target target = new Target();
enhancer.setSuperclass(Target.class);
enhancer.setCallback(new MethodInterceptor() {
@Override
public Object intercept(Object o, Method method, Object[] objects, MethodProxy methodProxy) throws Throwable {
System.out.println("Before invoking method..."+ method.getName());
Object obj = methodProxy.invokeSuper(o, objects);//option 1
// Object obj = methodProxy.invoke(target, objects);// option 2
//Object obj = method.invoke(target, objects);// option3
System.out.println("After invoking method: "+ method.getName());
return obj;
}
});
Target proxy = (Target) enhancer.create();
proxy.targetMethod();
}
static class Target {
void targetMethod() {
System.out.println("targetMethod executed....");
this.anotherMethod();
}
void anotherMethod(){
System.out.println("anotherMethod executed...");
}
}
static void amethod(){
System.out.println("amethod executed....");
}
}
输出结果:
Before invoking method…targetMethod
targetMethod executed…
Before invoking method…anotherMethod
anotherMethod executed…
After invoking method: anotherMethod
After invoking method: targetMethod
- 取消注释option 2,注释option 1,即执行method.invoke方法
输出结果:
Before invoking method…targetMethod
targetMethod executed…
anotherMethod executed…
After invoking method: targetMethod
- methodProxy也有invoke方法,执行结果同method.invoke,需要注意的是传入的参数是目标对象。
总结:从结果可以看出,methodProxy.invokeSuper拦截了所有的方法调用,而invoke方法只会拦截一次。因为method.invoke是使用了反射,调用了目标对象自己的方法。而invokeSuper是调用代理类中的增强方法。