AOPのAroundアノテーションを利用すると、AOP呼出対象のコントローラクラスのメソッド呼出前に、エラー画面に遷移する処理を呼び出すことができる。今回は、そのサンプルプログラムを作成してみたので、共有する。
前提条件
下記記事の実装が完了していること。
サンプルプログラムの作成
作成したサンプルプログラムの構成は以下の通り。
なお、上記の赤枠は、前提条件のプログラムから追加/変更したプログラムである。
コントローラクラスの内容は以下の通りで、初期表示画面とエラー画面に遷移する処理になっている。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 | package com.example.demo; import org.apache.commons.logging.Log; import org.apache.commons.logging.LogFactory; import org.springframework.stereotype.Controller; import org.springframework.web.bind.annotation.GetMapping; @Controller public class DemoController { //ログ出力のためのクラス private static Log log = LogFactory.getLog(DemoController.class); /** * 初期表示画面に遷移する * @return 初期表示画面 */ @GetMapping("/") public String index(){ log.debug("com.example.demo.DemoController.index() called."); return "index"; } /** * エラー画面に遷移する * @return エラー画面 */ @GetMapping("/toError") public String toError(){ log.debug("com.example.demo.DemoController.toError() called."); return "error"; } } |
また、AOPを利用したクラスの内容は以下の通りで、エラーフラグが設定されている場合は、AOP呼出対象のコントローラクラスのメソッド呼出前にエラー画面に遷移する処理を追加している。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 | package com.example.demo; import org.apache.commons.logging.Log; import org.apache.commons.logging.LogFactory; import org.aspectj.lang.ProceedingJoinPoint; import org.aspectj.lang.annotation.Around; import org.aspectj.lang.annotation.Aspect; import org.springframework.stereotype.Component; @Aspect @Component public class DemoInvocation{ //ログ出力のためのクラス private static Log log = LogFactory.getLog(DemoInvocation.class); //エラー発生を判定するフラグ private static boolean isErrorFlg = true; /** * Aroundアノテーションにより、指定したメソッドの前後に処理を追加する * Aroundアノテーションの引数には、Pointcut式を指定 * * @param jp 横断的な処理を挿入する場所 * @return 指定したメソッドの戻り値 */ @Around("execution(* com.example.demo.*Controller.*(..))") public Object writeLog(ProceedingJoinPoint jp){ //返却オブジェクトを定義 Object returnObj = null; //指定したクラスの指定したメソッド名・戻り値を取得 String signature = jp.getSignature().toString(); //開始ログを出力 log.debug("start writeLog : " + signature); log.debug("isErrorFlg : " + isErrorFlg); //エラーフラグが設定されている場合は、 //DemoControllerクラスのtoErrorメソッドを呼び出す if(isErrorFlg){ //次回呼出時はエラーにしないようfalseに設定 isErrorFlg = false; returnObj = "redirect:/toError"; return returnObj; } try { //指定したクラスの指定したメソッドを実行 returnObj = jp.proceed(); }catch(Throwable t){ log.error("error writeLog : ", t); } //終了ログを出力 log.debug("end writeLog : " + signature); //指定したクラスの指定したメソッドの戻り値を返却 //このように実行しないと、Controllerクラスの場合、次画面遷移が行えない return returnObj; } } |
さらに、初期表示画面、エラー画面のHTMLは以下の通り。
1 2 3 4 5 6 7 8 9 10 | <!DOCTYPE html> <html lang="ja"> <head> <meta charset="UTF-8"> <title>index page</title> </head> <body> これは初期表示画面です。 </body> </html> |
1 2 3 4 5 6 7 8 9 10 | <!DOCTYPE html> <html lang="ja"> <head> <meta charset="UTF-8"> <title>error page</title> </head> <body> エラーが発生しました。 </body> </html> |
その他のソースコード内容は、以下のサイトを参照のこと。
https://github.com/purin-it/java/tree/master/spring-boot-aop-to-error/demo
サンプルプログラムの実行結果
サンプルプログラムの実行結果は、以下の通り。
1) 以下のように、エラー発生を判定するフラグをfalseに変更する。
2) Spring Bootアプリケーションを起動し、「http:// (ホスト名):(ポート番号)」とアクセスすると、以下のように、初期表示画面が表示されることが確認できる。
3) このときのコンソールログの出力結果は以下の通りで、コントローラクラスのindexメソッドを呼び出した際、AOPを利用したクラスのwriteLogメソッドが最後まで実行されたことが確認できる。
4) 次に、以下のように、エラー発生を判定するフラグをtrueに変更する。
5) Spring Bootアプリケーションを起動し、「http:// (ホスト名):(ポート番号)」とアクセスすると、以下のように、エラー画面が表示されることが確認できる。
6) このときのコンソールログの出力結果は以下の通りで、コントローラクラスのindexメソッドを呼び出した際、AOPを利用したクラスのwriteLogメソッド内で、コントローラクラスのtoErrorメソッドを呼び出していることが確認できる。
要点まとめ
- AOPのAroundアノテーションを利用すると、AOP呼出対象のコントローラクラスのメソッド呼出前に、エラー画面に遷移する処理を呼び出すことができる。