Skip to content

Commit

Permalink
feat: 메서드 실행 시간 측정 AOP
Browse files Browse the repository at this point in the history
  • Loading branch information
loosie committed Apr 4, 2022
1 parent e4254bc commit 1f2a3d4
Show file tree
Hide file tree
Showing 5 changed files with 118 additions and 7 deletions.
64 changes: 60 additions & 4 deletions spring-aop/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,7 @@ implementation 'org.springframework.boot:spring-boot-starter-aop'
~~~


## 1. 메서드 파라미터, 리턴값 로그 AOP
## 1. 메서드 파라미터, 리턴값 AOP
로그를 찍어 어떤 Http Method가 실행되고 어떤 값이 리턴되는지 확인할 수 있어서 디버깅할 때 아주 유용하다.
- @Aspect: AOP 클래스에 선언
- @Pointcut
Expand All @@ -20,9 +20,7 @@ public class ParameterAop {
// controller 패키지 하위에 모두 적용
@Pointcut("execution(* com.example.springaop.controller..*.*(..))")
private void cut(){
}
private void cut(){}
@Before("cut()")
public void before(JoinPoint joinPoint){
Expand All @@ -49,3 +47,61 @@ public class ParameterAop {
}
~~~

<br>

## 2. 메서드 실행 시간 측정 AOP
### 2-1. Timer 애노테이션 생성
~~~
@Target({ElementType.TYPE, ElementType.METHOD})
@Retention(RetentionPolicy.RUNTIME)
public @interface Timer {
}
~~~

<br>

### 2-2. 실행 시간 측정할 API 예제
실행 시간 측정할 API에 @Timer 애노테이션을 명시해줌.
- 예시로 Thread.sleep 2초 설정
~~~
@Timer
@DeleteMapping("/delete")
public String delete() throws InterruptedException {
Thread.sleep(1000*2);
return "delete";
}
~~~

<br>

### 2-3. TimerAop 클래스 작성
- cut(): controller 하위 모든 패키지에 적용
- enableTimer(): @Timer 애노테이션이 명시된 메서드에 적용
- @Around: 타겟 메서드를 감싸서 특정 Advice를 실행한다는 의미이다
- proceed(): Proceed with the next advice or target method invocation 타겟 메서드 실행해서 리턴값 받아옴
~~~
@Aspect
@Component
public class TimerAop {
// controller 패키지 하위에 모두 적용
@Pointcut("execution(* com.example.springaop.controller..*.*(..))")
private void cut(){}
@Pointcut("@annotation(com.example.springaop.annotation.Timer)")
private void enableTimer(){}
@Around("cut() && enableTimer()")
public void around(ProceedingJoinPoint joinPoint) throws Throwable{
StopWatch stopWatch = new StopWatch();
stopWatch.start();
Object result = joinPoint.proceed(); // proceed() 메서드가 실행됨. 메서드 리턴이 있으면 result에 담음
stopWatch.stop();
System.out.println("total time = " + stopWatch.getTotalTimeSeconds());
}
}
~~~
Original file line number Diff line number Diff line change
@@ -0,0 +1,11 @@
package com.example.springaop.annotation;

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

@Target({ElementType.TYPE, ElementType.METHOD})
@Retention(RetentionPolicy.RUNTIME)
public @interface Timer {
}
Original file line number Diff line number Diff line change
Expand Up @@ -9,16 +9,17 @@
import org.aspectj.lang.annotation.Pointcut;
import org.aspectj.lang.reflect.MethodSignature;
import org.springframework.stereotype.Component;
import org.springframework.web.bind.annotation.DeleteMapping;

import com.example.springaop.annotation.Timer;

@Aspect
@Component
public class ParameterAop {

// controller 패키지 하위에 모두 적용
@Pointcut("execution(* com.example.springaop.controller..*.*(..))")
private void cut(){

}
private void cut(){}

@Before("cut()")
public void before(JoinPoint joinPoint){
Expand Down
33 changes: 33 additions & 0 deletions spring-aop/src/main/java/com/example/springaop/aop/TimerAop.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,33 @@
package com.example.springaop.aop;

import org.aspectj.lang.ProceedingJoinPoint;
import org.aspectj.lang.annotation.Around;
import org.aspectj.lang.annotation.Aspect;
import org.aspectj.lang.annotation.Pointcut;
import org.springframework.stereotype.Component;
import org.springframework.util.StopWatch;

@Aspect
@Component
public class TimerAop {

// controller 패키지 하위에 모두 적용
@Pointcut("execution(* com.example.springaop.controller..*.*(..))")
private void cut(){}

@Pointcut("@annotation(com.example.springaop.annotation.Timer)")
private void enableTimer(){ }

@Around("cut() && enableTimer()")
public void around(ProceedingJoinPoint joinPoint) throws Throwable{
StopWatch stopWatch = new StopWatch();
stopWatch.start();

Object result = joinPoint.proceed(); // proceed() 메서드가 실행됨. 메서드 리턴이 있으면 result에 담음
System.out.println("result = " + result);
stopWatch.stop();

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

}
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
package com.example.springaop.controller;

import org.springframework.web.bind.annotation.DeleteMapping;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.PathVariable;
import org.springframework.web.bind.annotation.PostMapping;
Expand All @@ -8,6 +9,7 @@
import org.springframework.web.bind.annotation.RequestParam;
import org.springframework.web.bind.annotation.RestController;

import com.example.springaop.annotation.Timer;
import com.example.springaop.dto.Member;

@RestController
Expand All @@ -25,4 +27,12 @@ public Member post(@RequestBody Member member){
return member;
}


@Timer
@DeleteMapping("/delete")
public String delete() throws InterruptedException {
Thread.sleep(1000*2);

return "delete";
}
}

0 comments on commit 1f2a3d4

Please sign in to comment.