4

我正在研究一个 Web 应用程序以解决一些问题。该应用程序使用 Tomcat、Jersey 和 Guice。其中一个问题发生在用于授权目的的 MethodInterceptor 中。这是方法,修剪到相关部分:

public Object invoke(MethodInvocation invoc) throws Throwable {
    // ...

    //Check that the annotation actually exists
    if(! invoc.getMethod().getDeclaringClass().isAnnotationPresent(Tool.class))
    {
        throw new BaseException("...");
    }

    // ...
}

现在的问题是一些“面向网络”的方法是从父类继承的,而没有在子类中被覆盖。如果我正确理解 getDeclaringClass() ,在这种情况下它将返回类,但我们真正想要的是子类。一些测试似乎证实了这一点——如果我覆盖子类中的方法一切都很好,但如果我不进行覆盖,则会引发异常。

那么,给定一个 MethodInvocation 对象,有没有办法将其追溯到实例化的“实际”类,而不是声明该方法的类?还是需要其他一些方法?最坏的情况是,我可以根据需要对每个方法进行注释,而不是对类进行注释。

抱歉,如果这是一个冗长的问题,可以轻松回答 - 我的 Java 相当生疏。

4

2 回答 2

8

很简单,需要getThis().getClass()在 MethodInvocation 上使用,而不是getMethod().getDeclaringClass()

    if(! invoc.getThis().getClass().isAnnotationPresent(Tool.class))
    {
        throw new BaseException("...");
    }

虽然在我的例子中,Guice 通过放入一个自动生成的子类(例如,一个以“$$EnhancerByGuice...”结尾的类名来解决这个问题,可以通过将一个向上移动一个来修复getSuperclass()

    if(! invoc.getThis().getClass().getSuperclass().isAnnotationPresent(Tool.class))
    {
        throw new BaseException("...");
    }
于 2012-11-15T21:46:33.717 回答
0

看起来答案是否定的。我创建了简单的测试来检查它:

    class Run implements Runnable {
        @Override
        public void run() {
        }
    }
    class Run2 extends Run{}
    Method method = Run2.class.getMethods()[0];
    System.out.println(method);

正如我们在调试窗口方法中看到的那样,没有 Run2 类的任何信息:

调试窗口中的方法

我想最好使用带有注释的实际方法,而不是在调用这些方法的实际类实例上。

于 2012-11-15T22:27:44.837 回答