AdSense

網頁

2020/6/1

Spring AOP 使用annotation對方法做log

Spring AOP使用annotation注釋的方式對標記的方法輸出log的方法如下。

範例環境

  • Spring Boot 2
  • Spring AOP
  • Log4j2
  • Lombok

在Maven或Gradle要加上Spring AOP依賴。

pom.xml

<dependency>
 <groupId>org.springframework.boot</groupId>
 <artifactId>spring-boot-starter-aop</artifactId>
</dependency>

build.gradle

dependencies {
    ...
    compile('org.springframework.boot:spring-boot-starter-aop')
    ...
}

建立一個用來標註方法的annotation @LogInfo。由於僅是用來標示要紀錄log的方法,因此@Target設為ElementType.METHOD

@LogInfo

package com.abc.demo.annotation;

import java.lang.annotation.ElementType;
import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;
import java.lang.annotation.Target;

@Target(ElementType.METHOD)
@Retention(RetentionPolicy.RUNTIME)
public @interface LogInfo {
}

建立AOP類別LogAspect,類別名稱前加上@Aspect。使用@Around("@annotation(com.abc.demo.annotation.LogInfo)")@LogInfo做切點,在pointcut designators @annotation()中使用完整類別名稱來指名要做切點的對象。

LogAspect

package com.abc.demo.aop;

import lombok.extern.log4j.Log4j2;
import org.aspectj.lang.ProceedingJoinPoint;
import org.aspectj.lang.annotation.Around;
import org.aspectj.lang.annotation.Aspect;
import org.springframework.stereotype.Component;

@Log4j2
@Aspect
@Component
public class LogAspect {

    @Around("@annotation(com.abc.demo.annotation.LogInfo)")
    public Object logInfo(ProceedingJoinPoint joinPoint) throws Throwable {
        String className = joinPoint.getSignature().getDeclaringType().getSimpleName();
        String annotatedMethodName = joinPoint.getSignature().getName();

        log.info("[{}.{}] start", className, annotatedMethodName);

        Object object = joinPoint.proceed();

        log.info("[{}.{}] end", className, annotatedMethodName);

        return object;
    }

}

在方法前面加上@LogInfo annotation,則此方法被調用的先後會執行,LogAspect.logInfo()jointPoint.proceed()前後的輸出日誌邏輯。

DemoController

package com.abc.demo.controller;

import com.abc.demo.annotation.LogInfo;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RestController;

@RestController
public class DemoController {

    @LogInfo
    @GetMapping(value = "/test")
    public void doTest() {
        System.out.println("do something...");
    }
}

測試結果如下。

2020-06-01 18:37:41.895  INFO 10899 --- [nio-8080-exec-2] com.abc.demo.aop.LogAspect               : [DemoController.doTest] start
do something...
2020-06-01 18:37:41.912  INFO 10899 --- [nio-8080-exec-2] com.abc.demo.aop.LogAspect               : [DemoController.doTest] end

沒有留言:

AdSense