6
7

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

More than 5 years have passed since last update.

Spring AOPの技術によるシステムログ出力を行う

Posted at

Spring AOPとは

 Spring Frameworkにおいて、DI(Dependency Injection、依存性注入)と並び重要な根幹技術となっているのが「AOP」というものです。
 AOPは、「Aspect Oriented Programming(アスペクト指向プログラミング)」の略です。アスペクトというのは、一般に「横断的関心事」と呼ばれるものです。

環境

  • spring
  • java8
  • Log4j

Spring AOPのアノテーション用語

1.@Aspect
  @Aspectをクラスにつけることで、そのクラスはAspectとして認識されます。
2.@Pointcut
  横断的な処理を挿入する場所(メソッド)を指定する。
3.@Before
  対象のメソッドの処理前に実行されるAdviceです。
4.@After
  対象のメソッドの処理結果に関わらず、必ず実行されるAdviceです。
5.@AfterReturning
  対象のメソッドの処理が正しく終了した場合にのみ実行されるAdviceです。
6.@AfterThrowing
  対象のメソッドの処理中に例外が発生した場合にのみ実行されるAdviceです。

実装デモ

LoggingAspect.java
package aspect.log;

import java.io.PrintWriter;
import java.io.StringWriter;
import java.util.Arrays;

import org.aspectj.lang.JoinPoint;
import org.aspectj.lang.Signature;
import org.aspectj.lang.annotation.AfterReturning;
import org.aspectj.lang.annotation.AfterThrowing;
import org.aspectj.lang.annotation.Aspect;
import org.aspectj.lang.annotation.Before;
import org.aspectj.lang.annotation.Pointcut;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.stereotype.Component;

/** ログ出力のアスペクトクラス. */
@Aspect
@Component
public class LoggingAspect {

  private static final Logger logger = LoggerFactory.getLogger(LoggingAspect.class);

  /** publicメソッドのポイントカット. システムエラーログ出力*/
  @Pointcut("execution(public * *(..))")
  private void publicLog() {}

  /** daoパッケージのポイントカット. db操作ログ出力 */
  @Pointcut("within(app.dao..*)")
  private void dbLog() {}

  /** webパッケージのポイントカット. リクエスト、レスポンスなどのログ出力*/
  @Pointcut("within(app.web..*)")
  private void webLog() {}

  /**
   * メソッド実行前にログ出力します.
   *
   * @param jp ジョインポイント
   */
  @Before("publicLog() && (dbLog() || webLog())")
  public void dobefore(JoinPoint jp) {

    Signature sig = jp.getSignature();
    String args = "無し";
    if(jp.getArgs() != null && jp.getArgs().length > 0 ) {
    	args = Arrays.toString(jp.getArgs());
    }
    logger.info("【操作開始】" +"メソッド:"+sig.getDeclaringTypeName() + "."+sig.getName()+"#入力パラメータ:"+ args);
  }

  /**
   * メソッド実行後にログ出力します.
   *
   * @param jp ジョインポイント
   */
  @AfterReturning(pointcut="publicLog() && (dbLog() || webLog())",returning="returnValue")
  public void doAfterReturning(JoinPoint jp,Object returnValue) {
    Signature sig = jp.getSignature();
    logger.info("【操作終了】"+"メソッド:"+sig.getDeclaringTypeName() + "."+sig.getName()+"#戻り値:" + returnValue);
  }

  /**
   * エラーが発生した場合、ログ出力します.
   *
   * @param jp ジョインポイント
   */
  @AfterThrowing (pointcut="publicLog() && (dbLog() || webLog())",throwing="ex")
  public void doAfterThrowing(JoinPoint jp,Exception ex) {
	  Signature sig = jp.getSignature();
	  StringWriter erMessage=new StringWriter();
	  ex.printStackTrace(new PrintWriter(erMessage));
	  logger.info("【エラー】" + "メソッド:"+sig.getDeclaringTypeName() + "."+sig.getName()+"#エラーメッセージ:" + erMessage.toString());

  }
}

最後に

最後まで読んでいただき、ありがとうございます。

参考:
https://docs.spring.io/spring/docs/5.0.5.RELEASE/spring-framework-reference/core.html#aop
https://iikanji.hatenablog.jp/entry/2018/04/26/204324

6
7
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
6
7

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?