【问题标题】:How to intercept abstract method如何拦截抽象方法
【发布时间】:2017-04-02 01:00:18
【问题描述】:

问题标题没有完全描述问题的含义,但我不能在标题限制内做到这一点。如果你帮我把它改得更方便,我会很高兴的。

我有一些如下描述的类层次结构:

抽象父类:

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!");
    }

}

我想拦截此层次结构中的每个方法调用并添加一些功能。即使方法是相互调用的,我也想每次都拦截它们。

我使用 cglib Enhancer 和 MethodInterceptor 实现来做到这一点:

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!

【问题讨论】:

    标签: java interceptor cglib


    【解决方案1】:

    这是您的委托方法的结果,您在另一个实例T origin 上调用拦截的方法。 Cglib 创建一个代理,它覆盖任何方法来实现你的MethodInterceptor。因此,拦截器仅在直接调用时应用。一个你传递给你的 origin 对象,拦截器因此不再有效。

    如果您想拦截任何方法调用,而不是委托,您需要使用 cglib 对象作为委托目标的替代品。您可以通过MethodProxy 实例调用原始方法。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2013-05-23
      • 2011-04-16
      • 1970-01-01
      • 2011-06-11
      • 2011-06-27
      相关资源
      最近更新 更多