728x90
반응형

외부 api에 접속할 때 간혹 가다 한 번이 아니라 두세 번 정도 시도를 해야 성공하는 경우가 있다. ( 외부 사이트가 불안정할 경우 )

 

그럴 때 만들 수 있는 Aspect가 있다. default 값은 꼭 정해주도록 하자.

 

1. Retry Annotation

backend/annotation/Retry

package web.backend.annotation;

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

@Target(ElementType.METHOD)
@Retention(RetentionPolicy.RUNTIME)
public @interface Retry {
    int value() default 3;
}

 

2. RetryAspect

backend/aop/RetryAspect

package web.backend.aop;

import lombok.extern.slf4j.Slf4j;
import org.aspectj.lang.ProceedingJoinPoint;
import org.aspectj.lang.annotation.Around;
import org.aspectj.lang.annotation.Aspect;
import web.backend.annotation.Retry;

@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;
    }
}

 

3. AopConfig

backend/aop/AopConfig

...

    @Bean
    public RetryAspect retryAspect() { return new RetryAspect(); }

...

 


테스트

Service 부분을 잠시 바꿔보고 해보자.

backend/module/user/UserService

...

    private static int seq = 0;

    @Retry(value = 2)
    public String save(User user) {
        if (seq == 0) {
            seq++;
            throw new IllegalStateException("예외 발생!!");
        }
        return "ok";
    }
    
...

 

실행 결과

728x90
반응형

+ Recent posts