エラーメッセージが示すように、アノテーションバインディングが一貫していないため、あなたが望むことはこの方法で行うことはできません.3つのアノテーションすべてを同時にバインドすることはできません.それらのうちの 1 つをバインドできます (複数のアノテーションを同じメソッドに割り当てない限り)。1 つがバインドされている場合、AspectJ は他の 2 つに代入するだけでこの矛盾に対処できると期待するかもしれませんが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);
}
}
}
ご覧のとおり、ポイントカットは、ポイントorg.jbehave.core.annotations.*
カット マッチングを大幅に絞り込むアノテーション付きのメソッドのみ@Given
をインターセプトします。@When
@Then
アドバイスでは、すべてのメソッド アノテーションをループします。これは、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)