어드바이스는 기본적으로 순서를 보장하지 않는다.
순서를 지정하려면 @Aspect
적용 단위로 org.springframework.core.annotation.@Order
애너테이션을 적용해야 함
aspect를 별도의 클래스로 분리해야 함
조인 포인트 실행 이전에 실행
target 메서드가 실행되기 전에 처리해야할 필요가 있는 부가 기능을 메서드 호출 전에 실행
Before Advice로 구현한 메서드는 일반적으로 리턴 타입이 void 형태
메서드에서 예외를 발생시킬 경우 대상 객체의 메서드가 호출되지 않게 됨
@Before("해당메서드의패키지명.Pointcuts.orderAndService()")
public void doBefore(JoinPoint joinPoint){
log.info("[before] {}", joinPoint.getSignature());
}
조인 포인트가 정상 완료 후 실행
메서드가 예외 없이 실행된 이후에 공통 기능을 실행
@AfeterReturning(value = "해당메서드의패키지명.Pointcuts.orderAndService()", returning = "result")
public void doReturn(JoinPoint joinPoint, Object result){
log.info("[return] {} return = {}", joinPoint.getSignature(), result);
}
메서드 호출 전 후에 수행하며 가장 강력한 Advice
메서드 실행 전&후, 예외 발생 시점에 공통 기능을 실행
Advice의 첫 번째 파라미터로 ProceedingJoinPoint를 사용
proceed()
를 통해 대상을 실행
proceed()
를 여러번 실행 가능
@Around
는 가장 강력한 어드바이스로 대부분의 기능을 제공하지만 target 등 고려해야할 사항이 있을 때 정상 작동이 되지 않는 경우가 있다.
@Before
, @After
와 같은 어드바이스는 기능은 적지만 원하는대로 작동되고 코드도 단순하며 각 애너테이션만 봐도 타겟 실행 전에 어떤 일을 하는지 명확하게 알 수 있다.
그래서 @Around
만을 사용해서 모두 해결하기 보다는 제약을 갖더라도 미연에 실수를 방지하는 것이 좋다. 제약을 두는 것은 문제 자체가 발생하지 않게 하며, 역할이 명확해져 좋은 설계로 이어질 수 있다.