修改使用注释的方法 [英] Modify a method using Annotations

查看:167
本文介绍了修改使用注释的方法的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我怎样才能改变什么的方法是用Java做什么?

How can I change what a method is doing in Java ?

我的意思是,我试图使用注解做出如下code

I mean, I am trying to use annotations to make the following code

@Anno1(Argument = "Option1")
public class TestClass
{       
    @Anno2
    public void test()
    {
    }

}

进入

public class TestClass
{
    private static StaticReference z;

    public void test()
    {
           z.invokeToAll();
    }

}

这是什么,我试图做一个很简单的例子。 Anno1 将有许多可能的组合,但是这不是我的问题为止。我的问题是如何code添加方法测试()

This is a very simplified example of what I am trying to do. Anno1 will have many possible combinations, but this is not my problem so far. My problem is how to add code to method test()

我要寻找可能的话一个更通用的解决方案。例如。方式来增加每一种code的方法(不只是一种 .invokeToAll()

I am looking for a more generic solution if possible. Eg. A way to add every kind of code in the method (not just a way to .invokeToAll())

到目前为止,我使用进口javax.annotation.processing中。*; 和我有以下的code,但我不知道怎么去从那里

So far I am using import javax.annotation.processing.*; and I have the following code, but I don't know how to go on from there

private void processMethodAnnotations(RoundEnvironment env)
{
    for (Element e : env.getElementsAnnotatedWith(Anno2.class))
    {
        //If it is a valid annotation over a method
        if (e.getKind() == ElementKind.METHOD) 
        {
            //What to do here :S
        }else
        {
            processingEnv.getMessager().printMessage(Diagnostic.Kind.WARNING,"Not a method!", e);               
        }           
    }
}

我已经找到一些关于Java反射,但我还没有发现任何来源帮助我,我在做什么。

I have found something about Java Reflection but I have not found any source to help me with what I am doing.

很显然,我在我的code继承AbstractProcessor ​​

我发现这个教程(http://www.zdnetasia.com/writing-and-processing-custom-annotations-part-3-39362483.htm),但这忧虑创建一个新的类,而不是只是改变的方法。和 javax.lang.model.elements 不提供编辑该元素(在我的情况重新presents的一种方法)的任何方式。

I have found this tutorial (http://www.zdnetasia.com/writing-and-processing-custom-annotations-part-3-39362483.htm) But this concerns creating a new class, not just changing a method. and the javax.lang.model.elements do not provide any way of editing that element (which in my case represents a Method).

我希望我的问题是明确的,内嵌的规则。如果不是请评论,我会澄清。谢谢你。

I hope my question is clear and inline with the rules. If not please comment and I will clarify. Thanks.

推荐答案

注释处理是错误的路要走你,从维基百科

Annotation processing is wrong way to go for you, from Wikipedia:

在Java源代码code编译,
  注释可以由处理
  编译器插件叫做注解
  处理器。处理器可以产生
  参考消息或创建
  额外的Java源文件或
  资源,而这又可能是
  编译和处理,但注解
  处理器不能修改带注释
  code本身。

When Java source code is compiled, annotations can be processed by compiler plug-ins called annotation processors. Processors can produce informational messages or create additional Java source files or resources, which in turn may be compiled and processed, but annotation processors cannot modify the annotated code itself.

人建议你正确的方式 - AOP。具体来说,你可以使用AspectJ的。 快速的结果的方式是(如果你使用Eclipse):

People suggested you right way - AOP. Specifically you can use AspectJ. "Quick result" way is (if you use Eclipse):

1)安装 AJDT (AspectJ开发工具)结果
2)创建AspectJ项目,并添加有你的类和注释结果
3)创建看点:

1) Install AJDT (AspectJ Development Tools)
2) Create AspectJ project and add there your classes and annotations
3) Create Aspect:

public aspect Processor {

    private StaticReference z;

    pointcut generic()
            // intercept execution of method named test, annotated with @Anno1
            // from any class type, annotated with @Anno2
        : execution(@Anno2 * (@Anno1 *).test())
            // method takes no arguments
        && args ();

    // here you have write what you want method actually does
    void around () : generic()  {
        z.invokeToAll();
    }


}

现在,你可以执行一个测试,你会看到,它的工作原理;)AJDT自动编译code你,所以不需要任何手工的工作要做,希望这就是你所谓的神奇;)

now you can execute a test and you will see that it works ;) AJDT compiles code for you automatically, so do not need any manual work to do, hope that's what you called "magic" ;)

更新:

如果在test()方法的$ C $,c取决于Anno1标注值,那么里面的方面,你可以得到它执行这样类注解:

if your code in test() method depends on Anno1 annotation value, then inside aspect you can get class annotation for which it is executed this way:

void around () : generic()  {

    Annotation[] classAnnotations = thisJoinPoint.getThis().getClass().getAnnotations();

    String ArgumentValue = null;
    for ( Annotation annotation : classAnnotations ) {
        if ( annotation instanceof Anno1 ) {
            ArgumentValue = ((Anno1) annotation).Argument(); 
            break;
        }
    }

    if ( ArgumentValue != null && ArgumentValue.equals("Option1")) {
        z.invokeToAll();
    }

}

其中,<一个href=\"http://www.eclipse.org/aspectj/doc/released/progguide/language-thisJoinPoint.html\">thisJoinPoint是一个特殊的引用变量。

where thisJoinPoint is a special reference variable.

UPDATE2:

如果您要添加的System.out.println(本)在你的方面,你需要写有的System.out.println( thisJoinPoint.getThis()),刚测试和它的作品。 thisJoinPoint.getThis()返回本,但不完全;其实这是对象变量,如果你想获得任何属性格式您需要使用投或使用反射。和 thisJoinPoint.getThis()不提供访问私有属性。

if you want to add System.out.println( this ) in your aspect, you need to write there System.out.println( thisJoinPoint.getThis() ), just tested and it works. thisJoinPoint.getThis() returns you "this" but not exactly; in fact this is Object variable and if you want to get any propery you need either to cast or to use reflection. And thisJoinPoint.getThis() does not provide access to private properties.

好了,现在看来,你的问题的答案,但如果我错过了什么,或者你用这种方式更多的问题/问题 - 随时问;)

Well, now seems that your question is answered, but if I missed anything, or you get additional question/problems with this way - feel free to ask ;)

这篇关于修改使用注释的方法的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆