2006/09/01

[aspectj-users] クラスアノテーションとメソッドアノテーションの組み合わせ

[aspectj-users] Combination of Class Annotation and Method Annotation matching

僕の投稿なんですが。

class Base{ void func(){} }

@Annot
class Derived extends Base{
 @Annot void func(){}
}

こんなクラスがある場合、execution(@Annot * (!@Annot *).*(..))というポイントカットが、Derived.funcにマッチするのは何故?って話。

結論としては、AspectJのマッチング仕様としては正しい動作らしい。
AspectJのマッチングは、実際にはメソッドそのものではなくそのシグネチャとマッチングを行っていて、1つのメソッドは複数のシグネチャを持ち、かつアノテーション等のデジネータは上書きされるってことらしい。つまり、Derived.funcは、親クラスのfuncのシグネチャを引き継ぐため、"Base.func"と"@Annot void (@Annot Derived).func"の2つのシグネチャを持つ。で、前述のポイントカットは上書きされて"@Annot Base.func()"になるので、Derived.funcがマッチするそうな。

これをマッチさせないための対処としてはexecution(@Annot * *.*(..)) && !within(@Annot *)というポイントカットを使うこと。

なんか釈然としないので、その後も議論の継続を試みたのだけど、止まってしまった。
クラスアノテーションもオーバーライドされれば(void Derived.funcが@Annot void (@Annot Base).func()と扱われれば)、すっきりすると思うんだけどなぁ。

0 件のコメント: