SpringのAOP実現の仕組み
SpringのAOP(Aspect-Oriented Programming)は、ダイナミック・プロキシに基づいて実装されています。Springでは、AOPはプロキシオブジェクトを利用することで横断的関心事を実装しています。
AOPでは、関心事はロギングやトランザクション管理など、プログラム内の特定の機能モジュールを意味します。横断的関心事とは、これらの機能モジュールがアプリケーション全体に存在し、ビジネスロジックと相互関係を持ち、独立したモジュールとして分離できないことを意味します。
Spring AOP は横断的関心事を実装するために代理パターンを採用しています。具体的には、Spring AOP は 2 つのタイプの代理を使用します。JDK の動的代理と CGLIB 代理です。
Spring AOPではJDKダイナミックプロキシを使用して、代理対象オブジェクトがインターフェースを実装している場合にプロキシオブジェクトを生成します。JDKダイナミックプロキシはインターフェースベースのプロキシで、実行時にターゲットオブジェクトのインターフェースを実装するプロキシクラスを生成し、ターゲットオブジェクトのメソッド呼び出しはプロキシクラスに委譲されることで横断的なロジックを実現します。
CGLIBプロキシ: インターフェイスを実装していない対象がプロキシされた場合、Spring AOPはCGLIBプロキシを使用してプロキシオブジェクトを生成します。CGLIBプロキシは、ターゲットオブジェクトを継承したサブクラスを生成して実装し、サブクラスはターゲットオブジェクトのメソッドをオーバーライドして、オーバーライドされたメソッドに横断的ロジックを追加します。
Spring AOP では、アスペクトとは横断的関心事をモジュール化して宣言したもので、ポイントカットとアドバスで構成されています。
AspectJにおけるポイントカットは、横断的関心事を定義するプログラム内のポイントです。通常は、表現言語を使用して定義されます。ポイントカットは、通知を適用するクラスやメソッドを指定できます。
通知は側面を定義した横断的なロジックであり、対象メソッドの呼び出し前に行われるロジック(前通知)、対象メソッドの呼び出し後に行われるロジック(後通知)、対象メソッドから例外が投げられた時に行われるロジック(例外通知)などがあります。
スプリングAOPでは、ターゲットオブジェクトのメソッドが呼び出されたときに、切断点一致ルールに基づいて、ターゲットメソッドの呼び出し前、呼び出し後、例外がスローされたときなどのタイミングで、対応する通知ロジックが動的に実行されます。この動的なプロキシメカニズムにより、開発者はソースコードを変更せずに、アスペクトを構成することで横断的関心事の機能を実現できます。