JavaのSpring FrameworkのDIを活用して、ロギングやセキュリティなどを関心事ごとに分離することを「アスペクト指向プログラミング(AOP)」と呼びます。このAOPを利用することで、インスタンスに外部から共通的な機能を入れ込むことができます。
出典:Spring徹底入門
🐹 AOPの用語
用語 | 説明 |
---|---|
Aspect | AOPの単位となる横断的な関心事を示すモジュール。ログ出力など |
Join Point | 横断的な関心事を実行するポイント。Springではメソッド実行時 |
Advice | 横断的な実装を行う箇所 |
Pointcut | 実行対象のJoin Pointを選択する表現(式)のこと |
Weaving | アプリケーションコードの適切なポイントにAspectを入れ込む処理のこと |
Target | AOP処理によって処理フローが変更されたオブジェクト |
🎳 Springで利用可能なAdvice
Advice | 概要 |
---|---|
Before |
Join Pointの前に実行される |
After Returning |
Join Pointが正常終了した後に実行される |
After Throwing |
Join Pointで例外がスローされた後に実行される |
After |
Join Pointの後に実行される |
Around |
Join Pointの前後で実行される |
出典:Spring徹底入門
🐯 Spring AOPのサンプル
出典:Spring徹底入門
Spring AOPはAOPフレームワークのASpectJを使っています。依存関係は次のとおりです。
<dependency> |
Aspectの実装例は次のとおりです。
// Aspectであることを示す |
Java ConfigのAOPを利用するためのアノテーション@EnableAspectJAutoProxy
を追加します。
この状態で実行してみます。
UserService userService = context.getBean(UserService.class); |
🏈 Pointcut式
AspectJではJoin Pointの選択をexecute指示子で表現できます。
出典:Spring徹底入門
Pointcut式で利用可能なワイルドカードは次のとおりです。
ワイルドカード | 説明 |
---|---|
* |
任意の文字列を表す。パッケージ表現なら任意のパッケージ位置階層を表す |
.. |
パッケージなら任意の0階層以上のパッケージを表す |
+ |
クラス名の後に指定することにより、そのクラスとそのサブクラス/実装クラスすべてを表す |
以下はPointcut式のサンプルです。
execution(String com.example.user.UserSerice.*(..))
- UserServiceクラスのStringが返り値のメソッドを対象とします
execution(* com.example.user.UserService.*(String, ..))
- UserServiceクラスの1つ目の引数がStringのメソッドを対象とします
🍣 Adviceの対象オブジェクトや引数を取得
JoinPoint
のgetTarget
メソッドでオブジェクト(Proxy)を取得できます。getArgs
メソッドで引数を取得できます。
(execution(* *..*ServiceImpl.*(..))) |
😼 Springで利用されているAOP
Springで利用されているAOPの利用例を紹介します。
@Transactional
:トランザクション管理
@Transactional
アノテーションを付与することでメソッドが正常終了すればコミットされ、実行時例外が発生したらロールバックします。
|
@PreAuthorize
:認可処理
@PreAuthorize
アノテーションでメソッドが呼ばれる前に特定の条件で認可されているか確認できます。
"ADMIN")) (hasRole( |
@キャッシュ処理
:キャッシュ処理
@Cacheable
アノテーションを付与することで、キー(引数など)のキャッシュがあればキャッシュを返すようにできます。
(user) |
@Async
:非同期処理
@Async
アノテーションを付与することで、時間のかかる処理を別スレッドで実行できます。
|
@Retry
:リトライ処理
@Retry
メソッドが正常終了するまでリトライ処理を行うことができます。
3) (maxAttempts = |