스프링 핵심 원리(고급편)

Ch12. 스프링 AOP(실전 예제) - 재시도 AOP

webmaster 2022. 4. 21. 16:03
728x90

Retry 어노테이션 작성

@Target(ElementType.METHOD)
@Retention(RetentionPolicy.RUNTIME)
public @interface Retry {
    int value() default 3;
}
  • 기본 Value를 줄 수가 있다

RetryAspect 작성

@Slf4j
@Aspect
public class RetryAspect {

    @Around("@annotation(retry)")
    public Object doRetry(ProceedingJoinPoint joinPoint, Retry retry) throws Throwable {//파라미터로 전달
        log.info("[retry] {} retry={}", joinPoint.getSignature(), retry);

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

        for (int retryCount = 1; retryCount <= maxRetry; retryCount++) {
            try {
                log.info("[retry] try count={}/{}", retryCount, maxRetry);
                return joinPoint.proceed();
            } catch (Exception e) {
                exceptionHolder = e;
            }
        }
        throw exceptionHolder;
    }
}
  • 재시도하는 애스펙트이다.
  • @annotation(retry) , Retry retry를 사용해서 어드바이스에 애노테이션을 파라미터로 전달한다.
  • retry.value()를 통해서 애노테이션에 지정한 값을 가져올 수 있다.
  • 예외가 발생해서 결과가 정상 반환되지 않으면 retry.value() 만큼 재시도한다

@Retry 적용

@Trace
@Retry(4)
public String save(String itemId){
    seq++;
    if(seq % 5 == 0){ //5번 한번 오류
        throw new IllegalStateException("예외 발생");
    }
    return "ok";
}

실행

@Slf4j
@Import({TraceAspect.class, RetryAspect.class})
@SpringBootTest
class ExamTest {

    @Autowired
    ExamService examService;

    @Test
    public void test(){
        for (int i = 0; i < 5; i++) {
            log.info("client request i = {}", i);
            examService.request("data" + i);
        }
    }
}
728x90