当前位置: 首页 > 知识库问答 >
问题:

AspectJ-多重@注释切入点

欧阳成弘
2023-03-14

我不能用“”运算符和多个注释来做切入点。我试图为一些JBehave注释创建一个切入点(@givid、@then、@when)。

    @Pointcut("@annotation(given)")
    public void jBehaveGivenPointcut(Given given) { }

为这三个注释创建切入点的语法是什么?因为我在其他切入点中使用了逻辑OR运算符,所以我假设它类似于:

    @Pointcut("@annotation(given) || @annotation(then) || @annotation(when) ")
    public void jBehaveGivenPointcut(Given given, Then then, When when) { }

但是它不起作用,我得到一个不一致的绑定异常。我尝试了其他组合,但找不到一个这样做的诀窍。

共有1个答案

邹玄裳
2023-03-14

您想要的不能这样做,因为正如错误消息所说,注释绑定是不一致的:您不能同时绑定所有三个注释,因为它们位于(可能是互斥的)或者是切入点的一部分,也就是说,通常只能绑定其中的一个(除非您将多个注释分配给同一个方法)。您可能期望AspectJ可以处理这种不一致性,只要将null赋给其他两个,如果其中一个是绑定的,但编译器现在不是这样工作的。

我可以提供一个变通方法,它涉及反射,而不是使用@annotation()绑定。

驱动程序应用程序:

package de.scrum_master.app;

import org.jbehave.core.annotations.Given;
import org.jbehave.core.annotations.Then;
import org.jbehave.core.annotations.When;

public class Application {
    public static void main(String[] args) {
        doGiven("foo");
        doSomething("bar");
        doWhen(11);
        doSomethingElse(22);
        doThen();
    }

    @Given("an input value") public static void doGiven(String string) {}
    @When("I do something") public static void doWhen(int i) {}
    @Then("I should obtain a result") public static boolean doThen() { return true; }
    public static void doSomething(String string) {}
    public static void doSomethingElse(int i) {}
}
package de.scrum_master.aspect;

import java.lang.annotation.Annotation;
import java.lang.reflect.Method;

import org.aspectj.lang.JoinPoint;
import org.aspectj.lang.annotation.Aspect;
import org.aspectj.lang.annotation.Before;
import org.aspectj.lang.annotation.Pointcut;
import org.aspectj.lang.reflect.MethodSignature;

@Aspect
public class JBehaveInterceptor {
    @Pointcut("execution(@org.jbehave.core.annotations.* * *(..))")
    public void jBehavePointcut() {}

    @Before("jBehavePointcut()")
    public void jBehaveAdvice(JoinPoint.StaticPart thisJoinPointStaticPart) {
        Method method = ((MethodSignature) thisJoinPointStaticPart.getSignature()).getMethod();
        for (Annotation jBehaveAnnotation : method.getAnnotations()) {
            if (jBehaveAnnotation.annotationType().getPackage().getName().equals("org.jbehave.core.annotations"))
                System.out.println(thisJoinPointStaticPart + " -> " + jBehaveAnnotation);
        }
    }
}

在建议中,我们循环了所有的方法注释,因为可能不仅仅有JBehave注释。如果任何注释包名称与相应的JBehave包匹配,我们就会执行一些操作(在本例中,将注释打印到标准输出中)。

我希望这能解决你的问题。我不能为您扩展AspectJ语言,这是我能想到的最好的。无论如何,这将产生以下输出:

execution(void de.scrum_master.app.Application.doGiven(String)) -> @org.jbehave.core.annotations.Given(priority=0, value=an input value)
execution(void de.scrum_master.app.Application.doWhen(int)) -> @org.jbehave.core.annotations.When(priority=0, value=I do something)
execution(boolean de.scrum_master.app.Application.doThen()) -> @org.jbehave.core.annotations.Then(priority=0, value=I should obtain a result)
 类似资料:
  • 我试图在方法注释上创建一个Aeyj切入点,但我总是用不同的方法失败。我使用的是aspectj自动代理(我在Spring上下文中没有配置其他编织)。我的类如下所示: 所以我想知道为什么aspectj不会创建切入点。我设法使用执行(**(…)使其工作抛出一些exc)这对我来说很好,但我仍然想知道我做错了什么。 另外,由于是在接口中定义的,我指定了实现类的注释,有没有办法让它以这种方式工作?其他代理机制

  • 我正在使用Spring AOP进行日志记录。我想创建一个切入点,该切入点适用于除具有特定注释的方法外的所有方法,但我不知道如何进行。我所发现的只是如何包含带有注释的方法。

  • 使用加载时间编织,纯AspectJ。 我们有2个注释和,以及一些带注释的方法。 现在我正在为具有多个注释的定义自己的围绕方面: 这行不通。然而,捕获方法myMethod2可以很好地用于单个注释: 我只想捕获签名中同时存在时间和计数注释的方法,并且我想使用注释值。有人知道如何做到这一点吗?

  • 服务实现 但是,如果我将注释移动到公共接口方法实现,我的方面就会被触发。我应该如何定义我的切入点或配置我的方面来使我的原始用例工作?

  • 我试图围绕使用自定义注释注释的方法定义一个切入点。注释有一个参数,我想在切入点定义中包含一个检查。 这是注释: 如何应用注释的示例: 现在我想有两个切入点定义,根据注释的内容选择这两种方法。 在注释本身上创建切入点相对容易: 这将匹配@MyAnno的每次出现。但是我如何定义两个切入点,一个将与包含的匹配,另一个将与包含的匹配

  • 我正在使用Spring的AspectJ和CGLIB代理。我有一个定义如下的方面,我希望它在具体的类上为公共方法提供建议,这些类是用批注“validatormethod”批注的: