/**
* Invoke the original method, on a different object of the same type.
* @param obj the compatible object; recursion will result if you use the object passed as the first
* argument to the MethodInterceptor (usually not what you want)
* @param args the arguments passed to the intercepted method; you may substitute a different
* argument array as long as the types are compatible
* @see MethodInterceptor#intercept
* @throws Throwable the bare exceptions thrown by the called method are passed through
* without wrapping in an <code>InvocationTargetException</code>
*/
public Object invoke(Object obj, Object[] args) throws Throwable {
try {
init();
FastClassInfo fci = fastClassInfo;
// 这里的obj应该传入的是目标对象或者其它目标对象(能调用当前这个方法的)
// 而绝对不能是代理对象,因为如果是代理对象,那么因为代理对象重写了这个方法,那么代理对象就会执行重写的方法,
// 而重写的方法又去调用MethodInterceptor里的方法,MethodInterceptor里的方法又调用这个方法,
// 这个方法又因为传过来的是代理对象,就会又调用代理对象重写的方法,从而出现死循环的情况
// 把这个fci.f1和fic.i1理解成目标类的方法的索引定位的一种快捷方式。那么既然是目标类中的方法,作为子类的代理类而言重写了该方法,
// 那么当然走子类的了,当然也可以走目标类自己的逻辑了,而不必传入代理类对象(逻辑上可以传,但传了会出问题),可以传入目标类型对象。
return fci.f1.invoke(fci.i1, obj, args);
} catch (InvocationTargetException e) {
throw e.getTargetException();
} catch (IllegalArgumentException e) {
if (fastClassInfo.i1 < 0)
throw new IllegalArgumentException("Protected method: " + sig1);
throw e;
}
}
/**
* Invoke the original (super) method on the specified object.
* @param obj the enhanced object, must be the object passed as the first
* argument to the MethodInterceptor
* @param args the arguments passed to the intercepted method; you may substitute a different
* argument array as long as the types are compatible
* @see MethodInterceptor#intercept
* @throws Throwable the bare exceptions thrown by the called method are passed through
* without wrapping in an <code>InvocationTargetException</code>
*/
public Object invokeSuper(Object obj, Object[] args) throws Throwable {
try {
init();
FastClassInfo fci = fastClassInfo;
// 这里必须传入代理对象,因为目标对象不能强转成代理类,而抛出ClassCastException异常
// 这里猜测可能代理类生成的class的这个方法中就是通过super.xxx()直接调用父类方法
// 把这个fci.f2和fic.i2理解成代理类的方法的索引定位的一种快捷方式,并且代理类里面的实现是直接通过super.xxx()直接调用父类方法实现的。
// 既然是代理类的方法那么肯定只有代理类对象才能调用,传个目标类对象过来,肯定会类型转换异常的
return fci.f2.invoke(fci.i2, obj, args);
} catch (InvocationTargetException e) {
throw e.getTargetException();
}
}
MethodInterceptor的MethodProxy参数
于 2021-06-13 23:20:42 首次发布