Spring 3.0 : そしてAOP

ここらでログ出力とかしたいよね。ということで、AOPです。

http://static.springsource.org/spring/docs/3.0.x/spring-framework-reference/html/aop.html

1. はじめに

  • Spring AOP は、ジョインポイントとしてメソッド実行時のみサポートしている
    • フィールドとかはサポート外
  • Spring AOP は、普通のAOPとちょっと違う。
    • SpringでEnterprise Applicationを作るときに必要な機能に特化しているので
    • 通常はSpringのIoCコンテナと一緒に使うことが前提
    • だからもっとどっぷりAOPしたい、というひとはAspectJをがっつりつかうべき
  • Spring AOPは標準のJ2SE 動的プロキシを使用している
    • CGLIBプロキシを使うことも可能

2.@AspectJ

  • @AspectJ を使用できるようにするには、設定ファイルに以下を宣言する
<aop:aspectj-autoproxy/>
  • これで@Aspect アノテーションをつければ自動的に宣言完了。クラスパスにあれば検出もしてくれる。
    • 私が試したときはそうだった
    • が、マニュアルには、自動検出させるには、@Componentアノテーションが必要だ、って書いてある。どっちが正しいのか。
  • ポイントカット(何か処理を挟みたい箇所)の宣言は、@Aspectでアノテートしたクラスのメソッドで宣言する
@Pointcut("execution(* transfer(..))")
private void anyOldTransfer() {}
    • @Pointcutをメソッドにつけて、ポイントカットを宣言する
    • これはtransferという名前のメソッドを実行した場合という意味
    • アノテートするメソッドは空でOK
    • executionの他に、within/this/target/args/@target/@args/@within/@annotation/beansというものがある。
    • AspectJと違い、this(プロキシそのもの)/ target(プロキシされたオブジェクト) に違いがある
    • Spring AOP はプロキシベースのため、protectedメソッドに振舞を追加することはできない。コンストラクタやprotected/privateのメソッドをかえたい場合はSpringによるnative AspectJ 織込を利用する。
  • ポイントカットの定義は組み合わせることができる。ポイントカットの定義を他の@Aspectクラスと共有することもできる
  • よいポイントカットを定義するには
    • Spring AOPではAspectJコンパイル時にポイントカットを処理する。これはポイントカットを見つけ出すマッチングのパフォーマンスを最適化するため
    • いくつかの条件を組み合わせてポイントカットを定義した場合、その宣言の順番を気にすることはない。AspectJが最適化してくれるから。
    • ただ、マッチングのパフォーマンスを最適化するためには、できるだけ探索する範囲を狭めることが大事。
    • ポイントカットは3種類に分類できる
      • Kinded: ジョインポイントの種類によって特定できるもの
      • Scoping: ジョインポイントの影響範囲によって特定できるもの
      • Contextual: 文脈までみないとわからないもの
    • よいポイントカットは少なくともKindedまたはScoping、どちらか特徴を含むべき。また、できればScopingの特徴を一つは含む方がよい。Kindedのみ、Contextualのみのポイントカットは処理時間とメモリ使用量に問題あり。


7.2.3.5 の途中までよみました。