7.1 Introduction
7.1.1 AOP concepts
AOPの中心概念を説明する。
Aspect トランザクション管理など、関心ごとのモジュールのこと。
「schema-based approach」(Javaでアスペクトを実装して設定ファイルに書く)か、
「@AspectJスタイル」(Javaアスペクトを実装して@AspectJを付与する)のどちらか。Join point Aspectを適用できるタイミング。
SpringAOPではメソッド呼び出し箇所のみ可能。Advice 特定のJoin Pointで実行されるアスペクトの処理。
実行タイミングに従いaround,before,afterといったAdviceがある。
Springではインターセプタによるアドバイスのモデルになっている。Pointcut Join Pointを特定するための表現。
特定の名前を持つメソッドなどを特定する表現がPointcut。
これに該当する箇所(JoinPoint)でAdviceが実行される。
SpringではAscpectJのPointcut表現言語を用いる。Introduction Adviceされたオブジェクトに対して、特定のメソッドや属性を追加宣言する。
SpringAOPでは、追加のインタフェースを定義することができる。Target object ひとつ以上のAspectが適用された(Adviceされた)オブジェクト。
SpringAOPはProxyの仕組みを使うので、これはProxyオブジェクトとなる。AOP proxy アスペクトを実現するためにSpringAOPが生成するオブジェクト。
SpringではInvocationHandlerかCGLIBのどちらか。Weaving アスペクトをアプリケーションのクラスにリンク付けること。
一般的にはコンパイル時、クラスロード時、実行時のタイミングが選択できるらしい。
Springでは実行時のWeavingのみサポート。Adviceの種類:
Before advice JoinPointの実行前。ただしJoinPointの実行を妨げることは、例外スロー以外ではできない。 After returning advice 例外を投げずに値をリターンした後。 After throwing advice 例外を投げた後。 After (finally) advice finallyの後。 Around advice インターセプタ。 Around adviceが一番一般的です。AOPの肝は、Pointcutによってjoinpointを絞り込むという概念で、これが旧来の類似した仕組みとの差別化ポイントになる。Pointcutによりオブジェクト指向の継承階層とは関係なくadviceを織り込むことができる。たとえばAround adviceを特定のパターンのメソッドに設定してトランザクション管理させるとかできる。
7.1.2 Spring AOP capabilities and goals
SpringAOPはJavaで実現される。特定のコンパイルプロセスは不要(実行時に織込むから)。SpringAOPはクラスローダ階層を制御したりする必要はないのでAPサーバ上で動かすには適している。SpringAOPはメソッド実行に対するアスペクトのみサポートする。Fieldに対するインターセプトは実装されていないが、AspectJなどの言語を使うことで実現することができる。
SpringAOPは完全なAOPを提供することは目指しておらず、SpringIOCにエンタープライズアプリケーションにおける一般的な問題を解決するための手段を提供することを目的としてる。なのでSpringAOPはSpringIOCと組み合わせて使われるのが普通。アスペクトは通常のBean定義と同じやり型で定義される感じになる。これは他のAOP実装とはは異なる。時々SpringAOPでは扱いにくいことがあるが、そういう場合はAspectJを用いて解決することができる。まぁあんまり必要無いだろけどね。
SpringAOPはAspectJと張り合うつもりはない。我々はSpringのようなプロキシベースのアプローチも、AspectJのようなリッチなAOPもどっちも大事だと思ってる。Spring2.0を使うとSpringとAspectJのシームレスな連携ができる。
注意書き:
Springのコンセプトは「侵略的ではない」ことです。つまりSpring独自のクラスを実装させたりAPIに依存させたり極力させないことです。しかし、時には依存させたほうが楽なこともあり、そういう手段を提供することもある。AOPにもそういういみで設定ファイルによる定義と@AspectJによる定義がある。設定ファイルのほうが侵略的ではないけど、最初に@AspectJのやり方から入るよ。僕らもアノテーションベースのアプローチの方が好きだからだ。
7.1.3 AOP Proxies
デフォルトではInvocationHandlerによるAOPプロキシとなる。この場合はインタフェースに対するプロキシのみ対応可能。SpringAOPではCGLIBによるプロキシ生成もサポートしてる。CGLIBはを使えばクラスに対するプロキシの作成もできる。CGLIBはデフォルトではインタフェースを実装しない業務クラスなどに対して用いられる。CGLIBの利用を強制する事もできる。
SpringAOPはProxyの仕組みで実現されていることは押さえておくべきである。