3

这是我的代码示例:

class foo extends afoo{

    @HTTPPost
    returnClass runTransaction(RequestData req){
        return sendData(req, returnClass.class)
    }

    @HTTPGet
    returnClass runTransaction2(RequestData req){
        return sendData(req, returnClass.class)
    }
}


abstract class afoo {

public <T> T sendData(ARestMessage req, Class<T> returnClassType)
    //here i need the annotation of the calling method
}

基本上我正在构建一个非常复杂的消息传递系统,我想尽可能多地在注释中放置切换和配置。

是的,我知道有一些库(比如 Google 反射)可以让这更容易,但为了让我使用它们,我必须做 4-6 个月的文书工作和与企业架构会议才能获得使用它们的批准. 看到项目必须在2个月内完成,我正在手工完成。

所以我正在做的是创建注释,开发人员可以注释方法,指示生成的服务期望发送数据的方式。这可能是 get、post、put 等。在所有服务类扩展的抽象类内部,是一个 senddata 方法。该方法必须能够确定使用哪个方法来调用它,也就是说,是通过 runTransaction 还是 runTransaction2,所以 sendData 拉取该方法注释,因此确切地知道如何将数据发送到服务。

现在我找到了这个(这是我的 sendData 方法中的第一行代码)

final Method callingMethod = this.getClass().getEnclosingMethod();

但它一直返回null。我已经阅读了几次关于它的 javadoc,但我不明白为什么它一直返回 null。

我知道我可以使用堆栈获取父调用者,但我不希望这样做,因为此应用程序与另一个执行大量 AOP 工作的应用程序共享应用程序服务器内存。AOP 工作非常擅长以意想不到的方式弄乱堆栈,所以我宁愿使用直接反射来解决这个问题。

有谁知道为什么这个方法一直返回null?是因为它包含在一个抽象类中,而不是我的 foo 类本身吗?有没有办法使用我更喜欢使用的技术来实现这一点?

谢谢

4

2 回答 2

4

该方法Class.getEnclosingMethod()不会像您认为的那样做。这是它的Javadoc:

如果此 Class 对象表示方法中的本地或匿名类,则返回一个 Method 对象,该对象表示基础类的直接封闭方法。否则返回 null。特别是,如果基础类是直接由类型声明、实例初始化程序或静态初始化程序包围的本地或匿名类,则此方法返回 null。

具体来说,它返回在该方法的上下文中定义的匿名内部类的外部封闭方法。我在您的描述中没有看到这些消息传递方法是从匿名/本地内部类调用的。这是代码中的示例(需要 jUnit):

import java.lang.reflect.Method;

import org.junit.Assert;
import org.junit.Test;

interface Introspector {
    public Method getEnclosingMethod();
}

public class Encloser {

    public Encloser() {
        super();
    }

    public Method noop() {

        final Introspector inner = new Introspector() {
            @Override
            public Method getEnclosingMethod() {
                return getClass().getEnclosingMethod();
            }
        };

        return inner.getEnclosingMethod();
    }

    @Test
    public void testEnclosingMethods() throws Exception {
        final Encloser encloser = new Encloser();
        Method method = encloser.getClass().getEnclosingMethod();
        Assert.assertNull(method);

        method = encloser.noop();
        Assert.assertNotNull(method);
    }
}

您当前的解决方案听起来很复杂。您是否打算沿着方法调用链(只能通过转储堆栈跟踪 btw 来做到这一点)并在进行大量反思后寻找注释?我预见了很多错误。坦率地说,采用某种构建器模式可能更适合您的场景。

于 2013-02-22T21:59:52.250 回答
0

在这里使用注释没有意义,只需将另一个参数传递给 method sendData()

于 2013-02-22T22:43:37.390 回答