ABOUT ME

-

Today
-
Yesterday
-
Total
-
  • 로그출력AOP & 재시도AOP
    Spring&SpringBoot 2025. 10. 21. 11:14
    @Target(ElementType.METHOD)
    @Retention(RetentionPolicy.RUNTIME)
    public @interface Trace {
        // 로그출력 AOP
    }
    @Target(ElementType.METHOD)
    @Retention(RetentionPolicy.RUNTIME)
    public @interface Retry {
        // 재시도 AOP
        int value() default 3;
    }

     

     

    @Slf4j
    @Aspect
    public class RetryAspect {
        @Around("@annotation(retry)")
        public Object doRetry(ProceedingJoinPoint joinPoint, Retry retry) throws Throwable {
            log.info("[retry] {} args={}", 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;
        }
    }
    @Slf4j
    @Aspect
    public class TraceAspect {
        @Before("@annotation(hello.aop.exam.annotation.Trace)")
        public void doTrace(JoinPoint joinPoint) {
            Object[] args = joinPoint.getArgs();
            log.info("[trace] {} args={}", joinPoint.getSignature().getName(), args);
        }
    }

     

     

    @Repository
    public class ExamRepository {
        private static int seq = 0;
    
        // 5번에 1번 실패하는 요청
        @Trace
        @Retry(4)
        public String save(String itemId) {
            seq++;
            if (seq%5==0) {
                throw new RuntimeException("<예외발생>");
            }
            return "ok";
        }
    }
    @Service
    @RequiredArgsConstructor
    public class ExamService {
        private final ExamRepository examRepository;
    
        @Trace
        public void request(String itemId) {
            examRepository.save(itemId);
        }
    }

     

     

    @Slf4j
    @SpringBootTest
    @Import({TraceAspect.class, RetryAspect.class})
    public class ExamTest {
        @Autowired
        ExamService examService;
    
        @Test
        void test() {
            for (int i = 0; i < 5; i++) {
                log.info("client request i={}", i);
                examService.request("data" + i);
            }
        }
    }

     

     

    728x90

    'Spring&SpringBoot' 카테고리의 다른 글

    JDBC  (0) 2025.11.12
    스프링 AOP 실무 주의사항  (0) 2025.10.21
    템플릿 메서드 패턴 & 전략 패턴 & 템플릿 콜백 패턴  (0) 2025.10.13
    로그추적기 - 동시성 문제  (0) 2025.10.02
    스프링 퀵 스타트 04  (0) 2025.09.22
Designed by Tistory.