それでは、もう少し詳しくアスペクトコードを見ていこう。もう一度先ほどのGreetingAspectを見てほしい。
public aspect GreetingAspect { |
リスト5 GreetingAspect(赤い部分は通常のJavaコード) |
call(* Messenger.printMessage(..)) |
ジョインポイント |
pointcut message() : call(* Messenger.printMessage(..)); |
ポイントカット |
before() : message() { |
アドバイス |
AspectJを使ったプログラミングを書くには次の3つのキーワードを理解する必要がある。
ジョインポイントはアスペクトをウィーブする「コード上のポイント」であり、1つ以上のジョインポイントをまとめた定義がポイントカットである。アドバイスは実際にウィーブするアスペクトの処理定義であり、ポイントカットに対してアドバイスを定義しておくことで、そのポイントカットで定義されている各ジョインポイントに対してアドバイスの処理が実行されることになる。
このGreetingAspectではmessage()というポイントカットを定義している(3行目)。ポイントカットを定義するための構文は次のようになる。
[アクセス修飾子] pointcut ポイントカット名([引数リスト]) : ポイントカット定義 |
ポイントカット定義の部分には次の表にあるような定義済みのポイントカットタイプを指定することができる。
メソッドの呼び出し | call() |
メソッドの実行 | execution() |
コンストラクタ呼び出し | call() |
コンストラクタの実行 | execution() |
クラスの初期化 | staticinitialization() |
インスタンスの初期化 | initialization() |
インスタンスの事前初期化 | preinitialization() |
フィールド値の取得 | get() |
フィールド値の設定 | set() |
例外処理 | handler() |
アドバイスの実行 | adviceexecution() |
表1 ポイントカットタイプ |
このポイントカットタイプの引数に対象クラスを指定することで、ジョインポイントが決定される。例えば、GreetingAspectでは次のようにジョインポイントが指定されている。
call(* Messenger.printMessage(..)) |
これはMessengerクラスのprintMessage() メソッドの呼び出しをジョインポイントとして指定し、そのジョインポイントに対して「message()」という名前のポイントカットを定義していることになる。また、ジョインポイントの指定には、次のようなワイルドカードとオペレータを使用することができる。
* | 「.」を含まない任意の文字列 |
.. | 「.」を含む任意の文字列 |
+ | サブクラスもしくはサブインターフェイス |
表2 ワイルドカード |
! | NOT |
&& | AND |
|| | OR |
表3 オペレータ |
beforeアドバイスは「事前処理」を定義するためのアドバイスである。つまりジョインポイントが実行される前に織り込む処理の定義である。反対にafterアドバイスは「事後処理」を定義する。つまりジョインポイントが実行された後に織り込む処理の定義である。aroundアドバイスはbeforeアドバイスやafterアドバイスに比べるとやや複雑である。aroundアドバイスはジョインポイントにおける処理に代わって実行される。
GreetingAspectでは5行目から7行目にbeforeアドバイスを定義しており、先に定義してあるmessage()ポイントカットをその対象としている。そして実際にウィービングする処理となる「Hello, 」の出力をJavaのプログラミングコードを使って記述している。つまりmessage()ポイントカットで指定されているジョインポイント(printMessage()メソッドの呼び出し)に対して事前処理として「System.out.print("Hello, ");」を実行するというわけである。
ここまでで簡単にAspectJプログラミングについて説明したが、実際にはもう少し複雑な言語仕様が取り決められているため、詳細はAspectJのサイトで公開されているリファレンスを参照していただきたい。
では次に、もう少し実践的なAOP導入の例として「ロギング」を紹介する。
Copyright © ITmedia, Inc. All Rights Reserved.