JH's Develog

[SpringCore] Custom Annotation과 AOP로 메서드 실행시간 측정하기 본문

Spring

[SpringCore] Custom Annotation과 AOP로 메서드 실행시간 측정하기

jhkimmm 2021. 12. 25. 02:49

이번 포스팅에서는 Custom Annotation과 @Around를 활용해서 메서드의 실행시간을 측정 해보겠습니다.

커스텀 어노테이션 생성

먼저 Timer라는 Custom Annotation을 생성해줍니다.

@Target({ElementType.TYPE, ElementType.METHOD})
@Retention(RetentionPolicy.RUNTIME)
public @interface Timer {}

@Target은 어노테이션을 붙일 수 있는 대상을 지정하는 역할을 하며 들어가는 파라미터는 다음과 같습니다.

  • ElementType.TYPE : 클래스, 인터페이스, 열거 타입에 어노테이션을 붙일 수 있습니다.
  • ElementType.CONSTRUCTOR : 생성자에 어노테이션을 붙일 수 있습니다.
  • ElementType.METHOD : 메서드에 어노테이션을 붙일 수 있습니다.
  • ElementType.FIELD : 메서드 필드에 어노테이션을 붙일 수 있습니다.

@Retention은 어노테이션이 언제까지 살아 남아 있을 지를 결정합니다.

  • RetentionPolicy.SOURCE : 컴파일러가 컴파일할 때 해당 어노테이션을 버립니다. 즉 소스코드(.java)까지는 남아있습니다.
  • RetentionPolicy.CLASS : 컴파일러가 컴파일할 때는 살아있지만 실제 메모리에서 실행되는 런타임시에는 사라지게 됩니다. 즉 클래스 파일(.class)까지는 살아있습니다.
  • RetentionPolicy.RUNTIME : 어노테이션이 런타임 중에도 살아있습니다. 대부분 RUNTIME 어노테이션을 사용하는 것으로 보입니다.

AOP클래스 생성

@Aspect
@Component
public class TimerAop {

    @Pointcut("@annotation(com.example.test1.annotation.Timer)")//Timer 어노테이션이 붙은 메서드에만 적용
    private void enableTimer(){}

    @Around("enableTimer()")
    public void around(ProceedingJoinPoint joinPoint) throws Throwable{ //메서드 실행시 걸린시간 측정
        StopWatch stopWatch = new StopWatch();
        stopWatch.start();

        Object result = joinPoint.proceed(); //메서드가 실행되는 부분

        stopWatch.stop();
        System.out.println("total time : "+stopWatch.getTotalTimeSeconds());
    }
}

@Pointcut의 표현식으로 @Timer 어노테이션이 붙은 메서드에만 Advice가 적용되도록 하고, 메서드의 시작 전, 종료 후에 시간을 측정해야 하므로 @Around를 사용해줍니다.

 

joinPoint.proceed()는 실제 Target 메서드가 실행되는 부분이므로, 이 부분 전후로 stopwatch를 start하고 stop해주어야 합니다. 총 걸린 시간을 콘솔창에 출력해서 확인해보겠습니다.

 

결과확인

@RestController
@RequestMapping("/api")
public class RestApiController {

    @DeleteMapping("/delete")
    @Timer
    public void delete(){
        //db logic
        try{
            Thread.sleep(1000);
        }catch (Exception e){
            e.printStackTrace();
        }
    }
}

데이터베이스에서 Delete를 수행한다고 가정하고 1초를 sleep하는 delete api를 생성하고 테스트 해보겠습니다.

<request>

<result>

 

Comments