[Spring AOP] 간단한 AOP 적용 예제 (메서드 실행시간 측정)

Kim Dae Hyun·2021년 8월 24일
1

Spring-AOP

목록 보기
2/6
post-thumbnail
post-custom-banner

AOP를 처음 접할때 Logging과 더불어 가장 많이 쓰이는 예제인 메서드 실행시간 측정 기능을 구현해볼께요.

🔎 AOP의 JoinPoint로 사용할 마킹용 어노테이션 작성

AOP의 적용 지점은 패키지, 클래스, 메서드 등 여러 방식으로 지정 가능합니다.
이번에는 어노테이션을 기반으로 적용지점을 설정해볼께요.

@Target({ElementType.METHOD, ElementType.ANNOTATION_TYPE})
@Retention(RetentionPolicy.RUNTIME)
public @interface ExeTimer {
}

위에 작성한 어노테이션 @ExeTimer가 붙은 메서드에 대해 AOP가 수행되도록 할 것입니다.


🔎 AOP 클래스 작성

@PointCut을 통해 모든 JointPoint에서 적용될 JoinPoint를 지정합니다.
@annotation 을 이용해서 작성한 어노테이션의 path를 지정합니다.

메서드 실행 전, 후로 실행시간을 측정하고자 합니다.
Spring AOP@Before, @AfterReturning등 메서드 전,후로 호출되는 메서드를 지원하는데 실행시간을 측정할 때에는 한 개 변수를 실행시간 전,후로 공유해야 하기 때문에 @Around를 사용합니다.

Stopwatch 클래스를 이용해서 시간을 측정했고 메서드 이름과 함께 로그가 찍히도록 설정했습니다.

@Slf4j
@Aspect
@Component
public class ExecutionTimer {

    // 조인포인트를 어노테이션으로 설정
    @Pointcut("@annotation(com.aop.annotation.ExeTimer)")
    private void timer(){};

    // 메서드 실행 전,후로 시간을 공유해야 하기 때문
    @Around("timer()")
    public void AssumeExecutionTime(ProceedingJoinPoint joinPoint) throws Throwable {

        StopWatch stopWatch = new StopWatch();

        stopWatch.start();
        joinPoint.proceed(); // 조인포인트의 메서드 실행
        stopWatch.stop();

        long totalTimeMillis = stopWatch.getTotalTimeMillis();

        MethodSignature signature = (MethodSignature) joinPoint.getSignature();
        String methodName = signature.getMethod().getName();

        log.info("실행 메서드: {}, 실행시간 = {}ms", methodName, totalTimeMillis);
    }
}

🔎 실행시간이 측정될 메서드 작성

매핑된 컨트롤러의 메서드로 요청이 왔을 때 해당 메서드의 실행시간을 측정하고자 합니다.
실행시간을 측정하는 많은 경우가 있는데 보편적으로 프로젝트의 큰 병목지점이 되는 DB 엑세스 부분이 많을 것 입니다.

/db-access로 요청이 왔을 때 DB에 접근한다고 가정하고 임의로 1초의 sleep을 주었습니다.
그리고 작성한 실행시간 측정 AOP를 적용시키기 위해 @ExeTimer를 추가합니다.

    @ExeTimer
    @GetMapping("/db-access")
    public String dbAccess() throws InterruptedException {

        Thread.sleep(1000); // DB 접근시 1초가 걸린다고 가정

        return "db";
    }

실행시간 측정 결과

잘 되었네요 ㅎ

감사합니다. 😁

profile
좀 더 천천히 까먹기 위해 기록합니다. 🧐
post-custom-banner

0개의 댓글