Home Spring Framework - AOP 구현 예시
Post
Cancel

Spring Framework - AOP 구현 예시

Retry AOP 구현

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
@Repository
public class ExamRepository {

  private static int seq = 0;

  /**
     * 5번에 1번 실패하는 요청
  */
  @Trace
  @Retry(value = 4)
  public String save(String itemId) {
    seq++;

    if (seq % 5 == 0) {
      throw new IllegalStateException("예외 발생");
    }
    return "OK";
  }
}
1
2
3
4
5
6
7
8
9
10
11
12
@Service
@RequiredArgsConstructor
public class ExamService {

  private final ExamRepository examRepository;

  @Trace
  public void request(String itemId) {
    examRepository.save(itemId);
  }

}
1
2
3
4
5
@Target(ElementType.METHOD)
@Retention(RetentionPolicy.RUNTIME)
public @interface Retry {
  int value() default 3;
}
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
@Slf4j
@Aspect
public class RetryAspect {

  // @annotaion(rety), Retry retry를 통해 어드바이스에 어노테이션을 파라미터로 전달
  @Around("@annotation(retry)")
  public Object doRetry(ProceedingJoinPoint joinPoint, Retry retry) throws Throwable {
    log.info("[retry] {} retry={}", joinPoint.getSignature(), retry);

    int maxRetry = retry.value();
    Exception execptionHolder = null;

    for (int retryCount = 1 ; retryCount <= maxRetry ; retryCount++) {
      try {
        log.info("[retry] try count={}/{}", retryCount, maxRetry);
        return joinPoint.proceed();
      } catch (Exception e) {
        execptionHolder = e;
      }
    }

    throw execptionHolder;
  }
}
1
2
3
4
5
6
7
8
9
10
11
12
13
14
@Import(RetryAspect.class)
@SpringBootTest
public class ExamTest {

  @Autowired
  ExamService examService;

  @Test
  void test() {
    for (int i = 0; i < 5 ; i++) {
      examService.request("data" + i);
    }
  }
}
2023-11-08 12:12:25.772  INFO 58418 --- [           main] hello.aop.exam.ExamTest                  : Started ExamTest in 0.659 seconds (JVM running for 1.463)
2023-11-08 12:12:26.047  INFO 58418 --- [           main] hello.aop.exam.aop.RetryAspect           : [retry] String hello.aop.exam.ExamRepository.save(String) retry=@hello.aop.exam.annotation.Retry(4)
2023-11-08 12:12:26.047  INFO 58418 --- [           main] hello.aop.exam.aop.RetryAspect           : [retry] try count=1/4
2023-11-08 12:12:26.051  INFO 58418 --- [           main] hello.aop.exam.aop.RetryAspect           : [retry] String hello.aop.exam.ExamRepository.save(String) retry=@hello.aop.exam.annotation.Retry(4)
2023-11-08 12:12:26.051  INFO 58418 --- [           main] hello.aop.exam.aop.RetryAspect           : [retry] try count=1/4
2023-11-08 12:12:26.052  INFO 58418 --- [           main] hello.aop.exam.aop.RetryAspect           : [retry] String hello.aop.exam.ExamRepository.save(String) retry=@hello.aop.exam.annotation.Retry(4)
2023-11-08 12:12:26.052  INFO 58418 --- [           main] hello.aop.exam.aop.RetryAspect           : [retry] try count=1/4
2023-11-08 12:12:26.052  INFO 58418 --- [           main] hello.aop.exam.aop.RetryAspect           : [retry] String hello.aop.exam.ExamRepository.save(String) retry=@hello.aop.exam.annotation.Retry(4)
2023-11-08 12:12:26.052  INFO 58418 --- [           main] hello.aop.exam.aop.RetryAspect           : [retry] try count=1/4
2023-11-08 12:12:26.052  INFO 58418 --- [           main] hello.aop.exam.aop.RetryAspect           : [retry] String hello.aop.exam.ExamRepository.save(String) retry=@hello.aop.exam.annotation.Retry(4)
2023-11-08 12:12:26.052  INFO 58418 --- [           main] hello.aop.exam.aop.RetryAspect           : [retry] try count=1/4
2023-11-08 12:12:26.052  INFO 58418 --- [           main] hello.aop.exam.aop.RetryAspect           : [retry] try count=2/4


참고

  • 스프링 핵심 원리 - 고급편(김영한)
This post is licensed under CC BY 4.0 by the author.

Spring Framework - 포인트컷

Spring Framework - AOP 주의사항