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 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 の途中までよみました。