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
참고
- 스프링 핵심 원리 - 고급편(김영한)