2017-11-23 11 views
1

私は、カスタム注釈で注釈が付けられたメソッドの周りにポイントカットを定義しようとしています。アノテーションには、ポイントカット定義にチェックを入れたいという1つのパラメータがあります。aspectj特定の注釈パラメータ値に一致するポイントカット

これは注釈です:

public @interface MyAnno { 
    String[] types; 
} 

注釈が適用されることができる方法の例:

public class MyClass { 
    @MyAnno(types={"type1", "type2"}) 
    public void doSomething() { 
    // ... 
    } 
    @MyAnno(types={"type3"}) 
    public void doSomethingElse() { 
    // ... 
    } 
} 

今、私はこれらの二つの方法を選択する2ポイントカット定義を持っていると思い、上のベース注釈の内容注釈自体にポイントカットを作成

は比較的簡単です。

@Pointcut("@annotation(myAnno)") 
public void pointcutAnno(MyAnno myAnno) { 
} 

@Pointcut("execution(* *(..)) && pointcutAnno(myAnno)") 
public void pointcut(MyAnno myAnno) { 
} 

これは@MyAnnoののすべての出現にマッチします。しかし、どのように私は2つのポイントカット、"type1""type3"

答えて

2

を含むtypesと他のマッチング@MyAnnoを含むtypesと1のマッチング@MyAnnoを定義することができます現在、AspectJのは、注釈値の許容される種類のサブセットのマッチング注釈値をサポートしています。残念ながら、使用している配列タイプはサポートされていません(クラスはサポートされていません)。この機能は、1.6.0 AspectJ README(https://eclipse.org/aspectj/doc/released/README-160.html)に記載されています。 「Annotation value matching」に関するセクションがあります。そこに述べたように、構文は、基本的な例のために実際には非常に直感的です:

enum TraceLevel { NONE, LEVEL1, LEVEL2, LEVEL3 } 

@interface Trace { 
    TraceLevel value() default TraceLevel.LEVEL1; 
} 

aspect X { 
    // Advise all methods marked @Trace except those with a tracelevel of none 
    before(): execution(@Trace [email protected](TraceLevel.NONE) * *(..)) { 
    System.err.println("tracing "+thisJoinPoint); 
    } 
} 

だからあなたは注釈で照合する値が含まれています。残念ながら、配列の場合はより複雑で、まだ実装されていません。あなたのポイントカットが「少なくとも配列の値にある」を意味するのか、「これは配列の値でのみこれを指すのか」を指定できるようにするには、もう少し構文が必要です。私はあなたがプログラムで、それはあなたの制約に合致するかどうかを確認するためにあなたのコード内のアノテーションを通じて掘るする必要があります怖い言語をサポートしない

execution(@MyAnno(types={"type1"}) * *(..)) { // exactly and only 'type1' 
execution(@MyAnno(types={"type1",..}) * *(..)) { // at least 'type1' 

:おそらくそれは..表記、多分このようなものを再利用します。

+0

アイデアをありがとうございました。それは私をたくさん助けます!配列のマッチングを行う方法がわからないことを期待していました。さて、ランタイムチェックが必要です。しかし、いかなる方法でも。どうもありがとうございました! –

1

条件付きポイントカットで行うことはできますが、注釈属性のランタイムテストが必要になります。

ネイティブアスペクト構文:

pointcut p(MyAnno myAnno): execution(* *(..)) 
    && @annotation(myAnno) 
    && if(Arrays.stream(myAnno.types()).anyMatch("type1"::equals)); 

アノテーションベースのアスペクト構文:

@Pointcut("execution(* *(..)) && @annotation(myAnno) && if()") 
public boolean pointcut(MyAnno myAnno) { 
    return !Arrays.stream(myAnno.types()).anyMatch("type1"::equals); 
} 

は、両方の例についてはjava.util.Arraysをインポートすることを忘れないでください。

現在のところ、AspectJバージョン1.8.13では、配列型のアノテーション属性でポイントカット式を静的に制限することはできません。そのため、このソリューションでは代わりにランタイムテストが必要になります。

+0

ありがとうございます!私はソリューションとして2つのcommensをマークしたいと思いますが、残念ながらStackoverflowは私を許さないでしょう。この問題を解決するためのあなたのやり方は私に大いに役立ちます! –

関連する問題