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

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

问题描述

如何更改 Java 中方法的作用?

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

我的意思是,我正在尝试使用注释来制作以下代码

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 将有许多可能的组合,但到目前为止这不是我的问题.我的问题是如何将代码添加到方法 test()

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()

如果可能,我正在寻找更通用的解决方案.例如.一种在方法中添加各种代码的方法(不仅仅是一种.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())

到目前为止我正在使用 import javax.annotation.processing.*; 并且我有以下代码,但我不知道如何从那里继续

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.

显然我在我的代码中扩展了 AbstractProcessor

我找到了这个教程(http://www.zdnetasia.com/writing-and-processing-custom-annotations-part-3-39362483.htm)但这涉及创建一个新类,而不仅仅是改变一个方法.并且 javax.lang.model.elements 不提供任何编辑该元素的方法(在我的例子中代表一个方法).

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 源代码编译时,注释可以通过称为注解的编译器插件处理器.处理器可以生产信息性消息或创建额外的 Java 源文件或资源,这反过来可能是编译和处理,但注释处理器不能修改注释代码本身.

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 会自动为你编译代码,所以不需要任何手动工作,希望这就是你所说的魔法";)

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() 方法中的代码依赖于 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();
    }

}

其中 thisJoinPoint 是一个特殊的参考变量.

where thisJoinPoint is a special reference variable.

更新 2:

如果你想在你的方面添加System.out.println(this),你需要在那里写System.out.println(thisJoinPoint.getThis()),刚刚测试,它的工作原理.thisJoinPoint.getThis() 返回this"但不完全正确;实际上,这是 Object 变量,如果您想获得任何属性,则需要进行强制转换或使用反射.并且 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天全站免登陆