AspectJ 의 포인트컷 표현식의 여러 지시자에 대해 학습했다. 이를 통해 메서드명, 타입, 어노테이션 등 다양한 포인트컷 매칭방식 적용이 가능해졌고, 타겟 메서드의 파라미터로 Advice 로 넘겨줄 수 있게 되었다.
이번 포스팅에서는 어노테이션 기반으로 스프링 AOP 를 적용해보는 실습을 진행하자.
ExamRepository 를 생성하였다. Repository 는 필드로 seq 를 갖는데, 이게 5의 배수일 때마다 exception 을 발생시킨다. 즉 클라이언트의 요청이 다섯번에 한번 꼴로 예외가 발생하는 상황을 가정하였다.
ExamService 는 ExamRepository.save 를 호출한다.
Trace 어노테이션을 생성했다.
포인트컷 표현식의 @annotation 지시자로 Trace 어노테이션과 매칭되는 Aspect 를 생성하였다. @Before 어드바이스로 실제객체 메서드 호출전에 로그를 출력한다. 실체객체 메서드를 joinPoint.getArgs 로 가져와서 출력한다.
Repository 의 메서드에 @Trace 를 추가하였다. 이제 해당 메서드는 TraceAspect 가 적용된다.
@Aspect 를 빈으로 등록 후 실행결과이다. AOP 가 적용되어 메서드 호출시 로그가 출력되며, 메서드를 호출하며 넘겨준 파라미터를 포인트컷이 advice 로 넘겨주어 함께 출력되는 것을 볼 수 있다.
Retry 어노테이션을 생성했다. 내부에 retry 제한 횟수를 설정하기 위해 value 속성을 추가하였다.
RetryAspect 를 생성했다. @annotation 으로 어노테이션이 추가된 메서드를 매칭시킨다. 이 때 Advice 에게 파라미터로 넘겨준다면, 해당 파라미터 이름만 적어주면 된다. 파라미터의 타입이 자동으로 매칭조건으로 넘어간다.
타겟메서드를 호출하다가 예외가 발생하지 않으면 타겟메서드로 넘어간다. 예외가 발생하면 예외를 저장해두었다가 어노테이션의 value 인 최대 반복횟수만큼 재시도를 수행한다.
최대 반복횟수 동안 계속 예외가 발생한다면 예외를 throw 로 예외를 던진다.
Repository 의 save 메서드에 @Retry 를 추가하였다. value 로 4를 넘겼으므로 최대 4회만큼 재시도를 수행한다.
@Aspect 를 빈으로 등록 후 실행하였다. 다섯번째 요청에서 예외가 발생하자. 재시도를 수행하고, 증가한 try count 가 출력된다.
어노테이션을 생성해 메서드에 추가하고, 포인트컷의 @annotation 지시자로 매칭시켰다. 그 결과 어노테이션을 추가하는 것만으로 손쉽게 부가기능을 적용할 수 있었다. 스프링의 @Transactional 과 같은 어노테이션 기반 AOP 는 이러한 방식으로 구현되어있다.