-
어드바이스 순서스프링/스프링 AOP 2023. 9. 22. 20:10
@Order 어노테이션을 이용해서 순서를 줄 수 있다. 그런데 이 어노테이션은 메서드에 부여하는 것이 아니라 클래스에 부여하는 것이다. 클래스 레벨의 @Aspect에 부여되는 것이니 @Aspect 안에 있는 두 개의 메서드에 @Order()를 넣는다해도 순서가 정해지지 않는다.
@Slf4j public class AspectV5Order { // hello.aop.order 패키지와 하위 패키지 @Pointcut("hello.aop.order.aop.Pointcuts.allOrder()") // 포인트컷 private void allOrder(){} // 클래스 이름 패턴이 *Service @Pointcut("hello.aop.order.aop.Pointcuts.orderAndService()") private void allService(){} @Aspect @Order(2) public static class LogAspect { @Around("allOrder()") // allOrder() 메서드를 넣어주면 됨 public Object doLog(ProceedingJoinPoint joinPoint) throws Throwable { log.info("[log] {}", joinPoint.getSignature()); // joinPoint 시그니처 (메서드 뭐 호출되었는지) return joinPoint.proceed(); } } @Aspect @Order(1) public static class TxAspect { @Around("allOrder() && allService()") public Object doTransaction(ProceedingJoinPoint joinPoint) throws Throwable { try { log.info("[트랜잭션 시작] {}", joinPoint.getSignature()); Object result = joinPoint.proceed(); log.info("[트랜잭션 커밋] {}", joinPoint.getSignature()); return result; } catch (Exception e) { log.info("[트랜잭션 롤백] {}", joinPoint.getSignature()); return e; } finally { log.info("[리소스 릴리스] {}", joinPoint.getSignature()); } } } }
클래스 안에 클래스를 만들어준다. 전체 클래스 파일 선언부가 아닌 각각의 클래스에 @Aspect 어노테이션을 붙여서 따로 사용되게 해야한다. 그리고 @Order() 어노테이션으로 순서를 부여하는 것이다.
요구사항이 트랜잭션을 실행하는 시간을 제외하고 로그를 찍는 것이라면, 트랜잭션이 1번, 시간로그가 2번이라면 트랜잭션이 실행되는 시간을 제외하고 시간이 찍히는 어드바이스 순서를 지정할 수 있다.
위의 사진을 보면 알겠지만 로직을 수행하고 클라이언트에게로 나갈 때에는 역순으로 나가게 된다.
Service 계층에서는 doTx, doLog 순으로 진행되며 Repository 계층에서는 doTx의 포인트컷에 해당되지 않기에 doLog만 수행하고 이때에는 Order(2)라고 할지라도 첫 번째로 수행된다.
'스프링 > 스프링 AOP' 카테고리의 다른 글
포인트컷 - execution (0) 2023.09.23 어드바이스 종류 (0) 2023.09.22 @Pointcut - 포인트컷 분리 (0) 2023.09.22 @Aspect 프록시 (0) 2023.09.20 빈 후처리기 (0) 2023.09.17