【问题标题】:How to call an external method before executing annotated method and pass the arguments如何在执行带注释的方法之前调用外部方法并传递参数
【发布时间】:2014-06-21 02:48:24
【问题描述】:

我正在开发使用Maven 构建到独立 JAR 中的 POJO 项目。为了可维护性,我正在考虑添加一种使用基于注释的检查的方法。在下面的代码中,我有一个带注释的方法,在调用该方法时,我希望另一个类中的另一个方法被执行并具有上下文感知,这样我就可以访问传递给原始方法的参数。

public class SomeClass {
    public static void someClassMethod(){

        ...

        get(new AnotherClass() {
            @CustomAnnotation
            public Object handle(ArgumentClass1 arg1, ArgumentClass2 arg2) {
                ...
            }
        });

        ...

    }
}

我知道这可以通过 AspectJ 完成,但我找不到如何实现此类功能的真实工作示例。所以我想问一个示例代码,或者指向工作示例的链接。

【问题讨论】:

  • 您在寻找pointcut on annotations吗?
  • @John,也许是的,因为我对术语不太熟悉。我查看了您指向的页面,但我看不到任何关于什么是切入点以及如何准确实现它的解释。我正在寻找一种最简单的方法来做我想做的事情 - 在执行被调用的方法之前执行一些检查。对我来说,注释似乎是要走的路,但我能找到的所有教程都是针对已经有很好知识的人而不是完成新手的人(我正在做很多 POJO,从来没有做过 AOP)。

标签: java annotations aop pojo


【解决方案1】:

我真的无法向您解释 AOP 基础知识。如果您不愿意至少阅读 AOP 教程并掌握诸如切面、连接点、切入点和建议等基本概念,就要求人们提供示例代码,这是错误的地方。我什至会在 AspectJ 中为您提供一个功能齐全的示例(见下文),但有什么用呢?你还会明白吗?我不打算提供 Maven 配置,因为这确实超出了范围,即使我确实知道如何使用 Maven 构建 AspectJ 代码。随意使用搜索引擎学习,然后返回具体问题,而不是“我懒得学习,请为我做”。

根据您的示例的参数类:

package de.scrum_master.app;

public class ArgumentClass1 {}

--

package de.scrum_master.app;

public class ArgumentClass2 {}

示例注释:

package de.scrum_master.app;

import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;

@Retention(RetentionPolicy.RUNTIME)
public @interface CustomAnnotation {}

根据您的样本抽象类:

package de.scrum_master.app;

public abstract class AnotherClass {
    public abstract Object handle(ArgumentClass1 arg1, ArgumentClass2 arg2);
}

带有一些示例方法的应用程序类:

package de.scrum_master.app;

public class SomeClass {
    public static void someClassMethod() {
        get(new AnotherClass() {
            @CustomAnnotation
            public Object handle(ArgumentClass1 arg1, ArgumentClass2 arg2) {
                return "dummy";
            }
        });
    }

    public static Object get(AnotherClass anotherClass) {
        return anotherClass.handle(new ArgumentClass1(), new ArgumentClass2());
    }

    private static void anotherClassMethod(String string, String string2) {}

    @CustomAnnotation
    private static void yetAnotherClassMethod(int i, int j) {}

    public static void main(String[] args) {
        someClassMethod();
        anotherClassMethod("foo", "bar");
        yetAnotherClassMethod(11, 22);
    }
}

如您所见,有一些静态方法,部分是公共/私有的,其中一个由 @CustomAnnotation 注释,而另一些则不是,一个包含一个匿名类,从上面具体化抽象类,还包含一个由注释的方法@CustomAnnotation。我们应该期望 yetAnotherClassMethod(int, int)handle(ArgumentClass1, ArgumentClass2) 被切面拦截,因为它们带有我们的目标注解。

最后,但同样重要的是,...

带有我们自定义注解的切面拦截方法:

package de.scrum_master.aspect;

import de.scrum_master.app.CustomAnnotation;

public aspect AnnotatedMethodInterceptor {
    Object around() : execution(@CustomAnnotation * *(..)) {
        System.out.println(thisJoinPoint);
        for (Object arg : thisJoinPoint.getArgs()) {
            System.out.println("  Checking argument " + arg);
        }
        return proceed();
    }
}

我没有检查示例中的参数,而是循环遍历参数数组以打印它们。不过,您可以在这里做任何您想做的事情。

现在请弄清楚 AOP 和 AspectJ 语法是什么。那里有足够的教程,只需使用您喜欢的搜索引擎或从http://www.eclipse.org/aspectj/docs.php开始。

示例代码控制台输出:

execution(Object de.scrum_master.app.SomeClass.1.handle(ArgumentClass1, ArgumentClass2))
  Checking argument de.scrum_master.app.ArgumentClass1@1bdf2b92
  Checking argument de.scrum_master.app.ArgumentClass2@58a58c89
execution(void de.scrum_master.app.SomeClass.yetAnotherClassMethod(int, int))
  Checking argument 11
  Checking argument 22

【讨论】:

  • 虽然这个答案可能有用,但它“有点”自大。你自己不这么认为吗?正如我在问题中所说,我主要来自 POJO 开发。而且我阅读和学习 maven 和 gradle 没有任何困难,有很多很好的教程和文档。至于 AOP——我能找到的只是教程,不是针对第一次决定接触它的人,而是针对那些已经熟悉 AspectJ 的所有术语和官方文档的人,这很糟糕。所以对不起,但这个答案的语气非常自大。至于例子 - 谢谢,我会试试的。
  • 你可以跳过引号,我承认我的回答很自大。所以呢?我的批评是实质性的,即使如此,我的回答也是建设性的。没有好的 AOP 教程是不正确的。如果您阅读eclipse.org/aspectj/doc/next/progguide/starting.html,您会发现它针对的是来自 POJO 开发的绝对初学者。我自己是 POJO 开发人员,我从不使用 Spring 或 EJB。我只是通过阅读教程和其他文档材料自学了 AspectJ。我还可以推荐 Ramnivas Laddad 的《AspectJ in Action》一书。祝你好运!
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2019-04-05
  • 1970-01-01
  • 2017-10-17
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多