어드바이스(Advice)
- Aspect를 언제 핵심 코드에 적용할지를 정의합니다.
- 부가 기능에 해당됩니다.
- 특정 조인 포인트에서 Aspect에 의해 취해지는 조치입니다.
어드바이스 순서
- 어드바이스는 기본적으로 순서를 보장하지 않습니다.
- 순서를 지정하고 싶으면 @Aspect 적용 단위로 org.springframework.core.annotation.@Order 애너테이션을 적용하여야 합니다.
- 어드바이스 단위가 아니라 클래스 단위로 적용할 수 있습니다.
- 하나의 Aspect에 여러 어드바이스가 존재하면 순서를 보장받을 수 없습니다.
- Aspect를 별도의 클래스로 분리하여야 합니다.
어드바이스 종류
Before
- 조인 포인트 실행 이전에 실행합니다.
- 타겟 메서드가 실행되기 전에 처리해야 할 필요가 있는 부가 기능을 메서드 호출 전에 실행합니다.
- Before Advice 구현한 메서드는 일반적으로 리턴타입이 void입니다.
- 리턴 값을 갖더라도 실제 Advice 적용 과정에 아무 영향이 없습니다.
- 주의점으로 메서드에서 예외를 발생시킬 경우 대상 객체의 메서드가 호출되지 않게 됩니다.
@before("hello.aop.order.aop.Pointcuts.orderAndService()")
public void doBefore(JoinPoint joinPoint) {
log.info("[before] {}", joinPoint.getSignature());
}
- 작업 흐름을 변경할 수 없습니다.
- 메서드 종료 시 자동으로 다음 타겟이 호출됩니다.(예외가 발생하면 다음 코드는 호출되지 않습니다.)
After returning
- 조인 포인트가 정상 완료 후 실행합니다.
- 메서드가 예외 없이 실행된 이후에 공통 기능을 실행합니다.
@AfterReturning(value = "hello.aop.order.aop.Pointcuts.orderAndService()", returning = "result")
public void doReturn(JoinPoint joinPoint, Object result) {
log.info("[return] {} return={}", joinPoint.getSignature(), result);
}
- 메서드 실행이 정상적으로 반환될 때 실행됩니다.
- returning 속성에 사용된 이름은 어드바이스 메서드의 매개변수 이름과 일치해야 합니다.
- returning 절에 지정된 타입의 값을 반환하는 메서드만 대상을 실행합니다.
after throwing
- 메서드가 예외를 던지는 경우에 실행합니다.
- 메서드를 실행하는 도중 예외가 발생한 경우 공통 기능을 실행합니다.
@AfterThrowing(value = "hello.aop.order.aop.Pointcuts.orderAndService()", throwing = "ex")
public void doThrowing(JoinPoint joinPoint, Exception ex) {
log.info("[ex] {} message={}", joinPoint.getSignature(), ex.getMessage());
}
- 메서드 실행이 예외를 던져서 종료될 때 실행합니다.
- throwing 속성에 사용된 이름은 어드바이스 메서드의 매개변수 이름과 일치해야 합니다.
- throwing 절에 지정된 타입과 맞은 예외를 대상으로 실행합니다.
after (finally)
- 조인 포인트의 동작(정상 또는 예외) 과는 상관없이 실행합니다.
- 예외 동작의 finally를 생각하면 됩니다.
- 메서드 실행 후 공통 기능을 실행합니다.
- 일반적으로 리소스를 해제하는 데 사용됩니다.
Around
- 메서드 호출 전후에 수행하며 가장 강력한 어드바이스입니다.
- 조인 포인트 실행 여부 선택, 반환 값 변환, 예외 변환 등이 가능합니다.
- 메서드 실행 전 & 후, 예외 발생 시점에 공통 기능을 실행합니다.
- 가장 강력한 어드바이스입니다.
- 조인 포인트 실행 여부 선택 -joinPoint.proceed()
- 전달 값 변환 - joinPoint.proceed(args[])
- 반환 값 변환
- 예외 변환
- try ~ catch ~ finally 가 들어가는 구문 처리 가능
- 어드바이스의 첫 번째 파라미터는 ProceedingJoinPoint를 사용해야 합니다.
- proceed()를 통해 대상을 실행합니다.
- proceed()를 여러 번 실행할 수 있습니다.
@Around만 있어도 모든 기능이 수행이 가능합니다.
- @Before, @After와 같은 어드바이스는 기능은 적지만 원하는 대로 작동되고 코드도 단순합니다.
- 각 애너테이션만 봐도 타겟 실행 전에 어떤 일을 하는지 명확하게 알 수 있습니다.
- 좋은 설계는 @Around만 사용해서 모두 해결하는 것보다는 제약을 가지더라도 실수를 미연에 방지하는 것입니다.
- 제약을 두면 문제 자체가 발생하지 않게 하며, 역할이 명확해집니다.
'Spring' 카테고리의 다른 글
[Spring] 조인 포인트(JoinPoint) (0) | 2023.04.13 |
---|---|
[Spring] 포인트컷(Pointcut) 표현식 (0) | 2023.04.12 |
[Spring] AOP(Aspect Oriented Programming) 용어 및 개념들 (0) | 2023.04.11 |
[Spring] AOP(Aspect Oriented Programming)가 필요한 이유 (0) | 2023.04.11 |
[Spring] DI(Dependency Injection) 종합 실습 (0) | 2023.04.10 |