昨日、アスペクト指向のAspectJの話を書いた。
そこで、元のソースはいいとして、横断的関心事として記述する、アスペクトの内容について。
■手順
手順は、以下の3ステップで考えるといいかも
(1)今回、どの箇所に割り込ませるかを、ジョインポイント(割り込み可能箇所)から選ぶ
ジョインポイントは、こんなかんじ。
・クラスの
→staticの初期化:staticinitialization
↓
・コンストラクタの
→呼び出し:call
→実行:execution
↓
・インスタンスの
→事前初期化?:preinitialization
→初期化:initialization
↓
・メソッドの
→呼び出し:call
→実行:execution
↓
・フィールドの
→参照:get
→代入:set
・例外
→実行:handler
・アドバイス
→実行:adviceexecution
各クラスやメソッド等の上記位置の割り込ませたいところを選ぶ
(2)上記(1)の箇所を、条件などをつけて、記述する(=ポイントカット記述)
昨日の例、execution(public String Sample.hello(..));
のように、選んだジョインポイントのあとに()で条件をつける。
条件には、* .. + ! && || などが使える。
また、アドバイスで変数を使えるように、ポイントカット変数を置くこともある。
(3)上記(2)の箇所で行う処理(=アドバイス)を記述する。
ポイントカットの前に入れるか、後に入れるかの指定
(before,after,例外を投げたときafter throwing、
スタブとして実行する=ジョインポイントの処理をしないaround)
をしたあと、ポイントカットをかいて、そのあと、処理内容を書く。
アドバイスの外部の変数を利用するには、上記ポイントカット変数を使うか、
thisJoinPointという、特殊な変数を使う。
■書き方
ポイントカットの書き方に2つあり、1つは昨日例のように、ポイントカットに名前をつけ、
pointcut helloCut():execution(public String Sample.hello(..));
あとで、その名前(ここではhelloCut())を利用して、ポイントカットを指定する方法、
before() : helloCut()
と、直接ポイントカットを書いてしまう方法
before() : execution(public String Sample.hello(..))
がある。
前者の例でいくと、昨日書いたように、
public aspect アスペクトの名前 {
pointcut ポイントカット名():ジョインポイント(条件(ポイントカット変数とか));
:
ポイントカット続く
:
beforeとかafterとか() : ポイントカット名()
{
アドバイスの処理
}
:
アドバイスつづく
:
}
となる。