问题标题并未完全描述问题的含义,但我无法在标题限制内进行。如果你帮我把它改成更方便,我会很高兴。
我有一些类层次结构如下所述:
AbstractParent:
public abstract class AbstractParent {
public void realParentMethod() {
System.out.println("invoking abstractMethod from realParentMethod");
abstractMethod();
}
public abstract void abstractMethod();
}
ChildImpl:
public class ChildImpl extends AbstractParent {
public void abstractMethod() {
System.out.println("abstractMethod implementation is running!");
}
}
我想在此层次结构中拦截每个方法调用并添加一些功能。即使方法是相互调用的,我也希望每次都能拦截它们。
我使用带有MethodInterceptor实现的cglib Enhancer来执行此操作:
import net.sf.cglib.proxy.Enhancer;
import net.sf.cglib.proxy.MethodInterceptor;
import net.sf.cglib.proxy.MethodProxy;
import java.lang.reflect.Method;
public class Main {
public static void main(String[] srgs) {
AbstractParent parentImpl = new ChildImpl();
Enhancer enhancer = new Enhancer();
enhancer.setSuperclass(AbstractParent.class);
enhancer.setCallback(new LocalMethodInterceptor(parentImpl));
AbstractParent proxyImpl = (AbstractParent) enhancer.create();
// straight calling abstractMethod
proxyImpl.abstractMethod();
System.out.println("-----------------");
// calling realParentMethod will lead to abstractMethod calling
proxyImpl.realParentMethod();
}
static class LocalMethodInterceptor<T> implements MethodInterceptor {
private T origin;
public LocalMethodInterceptor(T origin) {
this.origin = origin;
}
public Object intercept(Object obj, Method method, Object[] args, MethodProxy proxy) throws Throwable {
try {
System.out.println("intercept method["+method.getName()+"] before execution!");
return method.invoke(origin, args);
} finally {
System.out.println("cleanup after method["+method.getName()+"] execution!");
}
}
}
}
但问题是任何方法只拦截一次: 如果我调用抽象方法 - 它将被拦截。但层次结构的计划方式使您永远不必调用它(abstractMethod)。你只需调用realParentMethod就可以为你做所有的事情,这意味着它会从它自己调用abstractMethod。
在这个例子中,如果你调用realParentMethod只会拦截realParentMethod,那么就会跳过抽象方法。
以下是此示例的一些控制台输出:
intercept method[abstractMethod] before execution!
abstractMethod implementation is running!
cleanup after method[abstractMethod] execution!
-----------------
intercept method[realParentMethod] before execution!
invoking abstractMethod from realParentMethod
abstractMethod implementation is running!
cleanup after method[realParentMethod] execution!
答案 0 :(得分:1)
这是您委派方法的结果,您在另一个实例T origin
上调用截获的方法。 Cglib创建一个代理,它覆盖任何方法来实现MethodInterceptor
。因此,拦截器仅在直接调用时应用。一旦你传递给origin
对象,拦截器就不再有效了。
如果要拦截任何方法调用,而不是委托,则需要使用cglib对象替换委派目标。您可以通过MethodProxy
实例调用原始方法来调用原始方法。