2011-08-24 18 views
12

アノテーションを使用してインターフェイスメソッドをオーバーライドするメソッド実行に適用されるaspectjポイントカットを作成するにはどうすればよいですか?例えば:B.method()注釈自体を運ぶ場合@AspectJアノテーションを使用してインターフェイスメソッドをオーバーライドするメソッドのポイントカット

interface A { 
    @MyAnnotation void method(); 
} 
class B implements A { 
    void method(); 
} 

ポイントカットexecution(@MyAnnotation * *.*(..))のみ一致しません。これを行う別の方法がありますか?

答えて

10

ニコラスが指摘しているように、これはAspectJでは不可能です。ここで複数(http://www.eclipse.org/aspectj/doc/released/adk15notebook/annotations-pointcuts-and-advice.html部注釈継承とポイントカットマッチングから採取した)ことが不可能である理由の証拠である:Java 5の仕様によれば

は、非タイプ注釈は継承されず、タイプの注釈のみです@Inheritedメタアノテーションがある場合は継承されます。修飾子(visibility修飾子、注釈、およびthrows節)に対する結合ポイントのマッチングは、結合ポイントの主題に基づいているため(例ではb.method()になる)c2.aMethodの呼び出しは一致しませんメソッドが実際に呼び出されます)。

この同じ問題が発生したので、私はそのようなメソッドのポイントカットを書くことができる小さなメソッド/ライブラリを作成しました。ここでは、それはあなたの例のために働くだろうかです:

myAnnotationIsExecuted(): execution(public * *.*(..)) && 
      if(implementsAnnotation("@MyAnnotation()", thisJoinPoint)); 

OR

myAnnotationIsExecuted(): execution(public * A+.*(..)) && 
      if(implementsAnnotation("@MyAnnotation()", thisJoinPoint)); 

ライブラリから来ているimplementsAnnotation(String,JoinPoint)方法。実装されたメソッドに指定された注釈が含まれているかどうかを確認する基本的なメソッドです。

メソッド/ライブラリの詳細については、here.

3

更新

それは(オリジナルの答えを参照)、それは春に行うことができないことが表示されますので、私はあなたが実装するクラスの各メソッドに注釈を追加する必要があると言うでしょう。これを行うには明らかな方法がありますが、より自動的な方法を探している場合は、自分で書く必要があります。

特定のアノテーションを探す自家製ポストプロセッサーを想像すると、@ApplyThisAnnotationToAllWhoInheritMeと言うことができます。この注釈が見つかると、メンバーを継承するためのソースコードをスキャンし、コンパイルが行われる前に必要な箇所に要求された注釈を追加します。

これに関係なく、Spring AOPを使用している場合は、実装者メソッド上にある必要があるようです。もしこのクラスがあなたのコントロールできないものであれば、あなた自身のSpring AOPツールを書く必要があります。

Spring 3.0 Documentationから

オリジナル回答:

AspectJのは、インターフェイス上の注釈が継承されていないJavaの規則に従います。

私は、私は、これは世界的なルールだと思います7.8 Using AspectJ with Spring applicationsの一部で、あるセクション7.8.2 Other Spring aspects for AspectJ、このビットを発見しました。

+0

ありがとうございます。私のポイントカットが機能しない理由を説明しています。しかし、私は動作するものを探しています。 :-) –

+0

@ hstoerr:あなたの質問を編集した後、私は自分の答えを編集しました。それがまだ受け入れられないかどうか私に教えてください。 –

+1

春のドキュメンテーションは、私が欲しいものにマッチすることは不可能であるとは実際には言いません。私が試した単純なアプローチはうまくいきません。 Aspectjで私が考えることができない奇妙なことがあるかもしれません。だから私はまだ望んでいる。 :-) –

2
//introducing empty marker interface 
declare parents : hasmethod(@MyAnnotation * *(..)) implements TrackedParentMarker; 

public pointcut p1() : execution(* TrackedParentMarker+.*(..)); 

また、-XhasMemberコンパイラフラグを有効にする必要があります。

+0

残念ながらそれはそれをしません。これは、注釈を運ぶ少なくとも1つのメソッドを持つインタフェースを実装するすべてのクラスのすべてのメソッドに適用されます。しかし、それは、そのマーカーとのインタフェースメソッドを実装する1つのメソッドにのみ適用する必要があります。あるいは、少なくともAspectJで言うことができるなら、マークされたインターフェースメソッドで同じ名前のメソッドに。 –