AOPのAroundアノテーションを利用すると、AOP呼出対象のコントローラクラスのメソッド呼出前に、エラー画面に遷移する処理を呼び出すことができる。今回は、そのサンプルプログラムを作成してみたので、共有する。
前提条件
下記記事の実装が完了していること。
サンプルプログラムの作成
作成したサンプルプログラムの構成は以下の通り。

なお、上記の赤枠は、前提条件のプログラムから追加/変更したプログラムである。
コントローラクラスの内容は以下の通りで、初期表示画面とエラー画面に遷移する処理になっている。
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呼出対象のコントローラクラスのメソッド呼出前にエラー画面に遷移する処理を追加している。
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は以下の通り。
<!DOCTYPE html>
<html lang="ja">
<head>
<meta charset="UTF-8">
<title>index page</title>
</head>
<body>
これは初期表示画面です。
</body>
</html><!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呼出対象のコントローラクラスのメソッド呼出前に、エラー画面に遷移する処理を呼び出すことができる。





