获取调用方法的注释

时间:2013-02-22 21:55:39

标签: java reflection

以下是我的代码示例:

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个月的文书工作和与Enterprise Architecture的会议才能获得批准使用它们。看到项目必须在2个月内完成,我是手工完成的。

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

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

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

但它一直返回null。我已多次阅读javadoc并且我不明白为什么它一直返回null。

我知道我可以使用堆栈获取父调用者,但我不想这样做,因为此应用程序与另一个执行AOP TON工作的应用程序共享app服务器内存。 AOP的工作非常善于以非预期的方式搞乱堆栈,所以我宁愿用直接反射来解决这个问题。

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

感谢

2 个答案:

答案 0 :(得分:4)

方法Class.getEnclosingMethod()没有按照您的想法执行。这是它的Javadoc:

  

如果此Class对象表示a中的本地或匿名类   方法,返回一个表示立即封闭的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)并在做了一些大量的反射之后寻找注释?我预见到很多错误。坦率地说,使用某种构建器模式可能会更适合您的场景。

答案 1 :(得分:0)

这里使用注释毫无意义,只需将另一个参数传递给方法sendData()