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>