타입별 Advice

seongmin·2022년 10월 17일
0

Spring

목록 보기
15/38
post-thumbnail

어드바이스(Advice)

  • Aspect를 언제 핵심 코드에 적용할지를 정의한다.
  • 부가 기능에 해당한다.
  • 특정 조인 포인트에서 애스팩트에 의해 취해지는 조치다.

Advice 순서

어드바이스는 기본적으로 순서를 보장하지 않는다.

  • 순서를 지정하고 싶으면 @Aspect 적용 단위로 org.springframework.core.annotation.@Order 애너테이션을 적용해야 한다.

    • 어드바이스 단위가 아니라 클래스 단위로 적용할 수 있다.

    • 하나의 애스펙트에 여러 어드바이스가 존재하면 순서를 보장 받을 수 없다.

  • 애스펙트를 별도의 클래스로 분리해야 한다.

Advice 종류

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만 사용해서 모두 해결하는 것보다는 제약을 가지더라도 실수를 미연에 방지하는 것이다.

  • 제약을 두면 문제 자체가 발생하지 않게 하며, 역할이 명확해진다.

0개의 댓글