Spring Boot + MySQLでシンプルなWeb REST APIサーバを実装する - Qiita
Outline
Spring AOPを利用してSpring Boot アプリケーションのログを落とす。
利用するロガーはSLF4J+Logback。
SLF4J
javaのロギングのインタフェースの仕様。
これを用いることで、Loggerの実装を隠蔽することができる。
Logback
AOP
Aspect Oriented Programming
クラスやメソッドに横断的に存在する処理(まさにロギングとか)を一箇所にまとめて記述しようという考え方。
Springではアノテーションを用いて実装されている。
dependencies
spring-boot-starter-webを利用していれば使えるので、特に追加等は必要ない。
LoggingAspects.java
ログの出力を実行するクラス。
AOPを利用してこのメソッドを様々な箇所に注入する。
package com.example.springapi.aop;
import org.aspectj.lang.JoinPoint;
import org.aspectj.lang.annotation.*;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.stereotype.Component;
import java.util.Arrays;
@Aspect
@Component
public class LoggingAspects {
private static final Logger logger = LoggerFactory.getLogger(LoggingAspects.class);
@Before("within(com.example.springapi.application.controller.UserController)")
public void controllerStartLog(JoinPoint joinPoint) {
String string = joinPoint.toString();
String args = Arrays.toString(joinPoint.getArgs());
logger.info("Start {}, args: {}", string, args);
}
@AfterReturning("within(com.example.springapi.application.controller.UserController)")
public void controllerEndLog(JoinPoint joinPoint) {
String string = joinPoint.toString();
String args = Arrays.toString(joinPoint.getArgs());
logger.info("End {}, args: {}", string, args);
}
@AfterThrowing(value = "within(com.example.springapi.application.controller.UserController)", throwing = "e")
public void afterException(JoinPoint joinPoint, Exception e) {
String string = joinPoint.toString();
String args = Arrays.toString(joinPoint.getArgs());
logger.error("Error!, Exception: {}, {}, args = {}", e.getMessage(), string, args);
}
}
@Aspect
AspectJというAOPライブラリのアノテーション。
実際はSpringBootがAOPの機能を実装しているが、アノテーションのみAspectJのを使ってるらしい。
@Aspectと@Compornentを付与することで、AOPのコンポーネントとして登録され、横断的に注入することが可能になる。
@Before
Adviceと呼ばれる。
注入したメソッドのどのタイミングでAspectを呼び出すかを指定する。
AfterとかAfterThrowingとかいろいろある。
within(...)
PointCutと呼ばれる。
注入するメソッドの条件。
Spring AOP ポイントカット指定子の書き方について
JoinPoint
注入されたメソッドに関する情報が格納されているクラス。