백엔드/Spring

[Spring] Spring AOP - Pointcut

kwang2134 2024. 11. 10. 16:43
728x90
반응형
728x90

Pointcut

  • 특정한 메서드 또는 메서드 실행 지점을 타겟팅하는 조건을 정의하는 표현식
  • Advice 가 적용될 메서드를 지정하는 역할
  • 어떤 메서드에 어드바이스를 적용할지 결정하는 규칙을 정의

표현식

  • 기본적으로 AspectJ 표현식 언어를 사용
지시자(리턴타입 패키지.클래스.메서드(매개변수))
  • 지시자: 포인트컷 표현식 시작 키워드
  • 리턴타입: 메서드의 리턴 타입
  • 패키지.클래스.메서드: 해당 메서드를 포함하는 클래스와 메서드의 이름을 지정
  • 매개변수: 메서드의 파라미터 목록

연산자

  • 와일드 카드(*): 모든 리턴 타입이나 모든 클래스, 모든 메서드 이름, 모든 파라미터 타입을 의미 -> 1개의 변수 의미
  • 두 점(..): 0개 이상의 매개변수 의미
  • 논리 연산자 &&, ||: 두 개 이상의 조건을 결합 가능

예시

//모든 메서드 실행 포인트컷
execution(* *.*(..))

//특정 패키지 내의 모든 메서드 실행 포인트컷
execution(* com.example.service.*.*(..))

//특정 클래스의 특정 메서드 실행 포인트컷
execution(* com.example.service.UserService.save(..))

//리턴 타입 포인트컷
execution(String com.example.service.UserService.findUser(..))

//메서드 이름 포인트컷
execution(* *.*find*(..))

//매개변수 개수 또는 타입 포인트컷
execution(* com.example.service.UserService.updateUser(int, String))

//타입 포인트컷
execution(* com.example.service.*.*(String))

//논리 연산자
execution(* com.example.service.*.*(..)) && execution(* com.example.service.UserService.*(..))

Pointcut Designators - 포인트컷 지시자

  • 메서드 실행 지점을 정확하게 지정하기 위해 사용되는 키워드

execution 

  • 메서드 실행 지점을 지정하는 데 사용
  • 리턴 타입, 클래스, 메서드 이름, 매개변수 등을 기반으로 포인트컷을 정의
  • 부모 타입 매칭 허용
execution([리턴타입] [패키지.클래스.메서드명]([매개변수]))

//예시
execution(* com.example.service.UserService.save(..))

*: 모든 리턴 타입
com.example.service.UserService: UserService
save: save 메서드
(..): 모든 매개변수

//부모 타입 매칭
execution(* com.example.Parent(..))
Parent의 자식 타입도 매칭

within

  • 클래스나 패키지 범위 내에서 실행되는 메서드를 선택하는 데 사용
  • 메서드 실행이 특정 클래스나 패키지 내에 있을 때만 어드바이스를 적용
//문법
within([패키지.클래스]...)

//com.example.service 패키지 내의 모든 클래스에서 실행되는 메서드에 대해 어드바이스를 적용
within(com.example.service.*)

args

  • 매개변수 타입에 따라 포인트컷을 정의
  • 메서드가 특정 매개변수 타입을 가질 때만 어드바이스를 적용
//문법
args([매개변수 타입])

//매개변수가 String 타입인 모든 메서드에 적용
args(String)

//매개변수가 String 타입으로 시작하는 모든 메서드에 적용
args(String, ..)

@target

  • 특정 타겟 객체가 어노테이션을 가지고 있을 때 해당 메서드에 어드바이스를 적용
  • 타겟 객체가 어노테이션을 가지고 있는지를 기준
  • 부모 타입의 메서드도 적용
//문법
@target([애너테이션 타입])

//@Transactional 어노테이션이 적용된 객체의 해당 메서드에 어드바이스 적용
//해당 객체의 클래스와 부모 타입의 클래스의 메서드에도 적용
@target(com.example.annotation.Transactional)

@within

  • 특정 클래스 또는 메서드가 특정 애너테이션을 가지고 있는 경우 해당 메서드에 어드바이스 적
  • 클래스 수준 필터링
  • 자기 자신의 클래스만 적용 -> 부모 타입 적용 X
//문법
@within([애너테이션])

//@Transactional 어노테이션이 적용된 클래스의 모든 메서드에 어드바이스를 적용
@within(com.example.annotation.Transactional)

@annotation

  • 메서드에 특정 애너테이션이 있을 때 해당 메서드에 대해 어드바이스를 적용
  • 메서드 수준의 필터링
//문법
@annotation([애너테이션])

//@Loggable 어노테이션이 붙은 메서드에 어드바이스 적용
@annotation(com.example.annotation.Loggable)

this

  • 프록시 객체가 특정 타입의 인스턴스를 구현하고 있을 때 적용
  • 메서드를 호출하는 객체가 특정 인터페이스나 클래스를 구현하는 경우에만 어드바이스를 적용
  • JDK 동적 프록시 또는 CGLIB 프록시가 적용된 객체에 대한 필터링에 사용
  • JDK 동적 프록시의 경우 인터페이스가 아닌 구현 클래스로 지정 될 경우 의도치 않은 결과 발생
//문법
this([타입])

//UserService 타입의 프록시 객체에 의해 호출되는 모든 메서드에 어드바이스를 적용
this(com.example.service.UserService)

//JDK 동적 프록시 사용 시 구현 클래스로 지정이 된 경우 
//인터페이스로 생성 되는 JDK 동적 프록시는 구현 클래스를 알 수 없어 적용 되지 않음
this(com.example.service.UserServiceImpl) -> 적용 x

target

  • 타겟 객체가 특정 타입인 경우에만 어드바이스를 적용
  • 프록시 객체가 아닌 실제 타겟 객체에 대한 필터링
//문법
target([타입])

//UserService 타입의 실제 객체에 의해 호출되는 모든 메서드에 어드바이스를 적용
target(com.example.service.UserService)

bean

  • 특정 빈 또는 빈 이름을 기준으로 포인트컷을 정의하는 데 사용
  • 주로 빈 이름에 맞는 메서드 실행에 어드바이스를 적용
  • 빈의 이름 또는 빈의 타입을 기준으로 어드바이스를 적용 가능 -> 특정 빈에 대한 메서드 호출에만 어드바이스를 적용 가능
//문법
bean([빈 이름])

//userService 빈에서 실행되는 모든 메서드에 적용
bean("userService")

//user로 시작하는 모든 빈에 대해 적용
bean("user*")

//특정 타입 빈에 적용
bean("com.example.service.UserService")

@args

  • 메서드의 매개변수에 적용된 애너테이션을 기준으로 포인트컷을 정의
  • 메서드의 파라미터가 특정 애너테이션을 가지고 있을 때만 포인트컷을 적용 가능
//문법
@args([애너테이션 클래스], [파라미터 타입])

//메서드의 매개변수 중에 @Validated 애너테이션이 적용된 경우에만 어드바이스를 적용
@args(com.example.annotation.Validated)
public void someMethod(String data) {
    // 메서드 내용
}

요약

포인트컷 지시자 설명
execution 메서드 실행 지점 지정 (메서드 이름, 리턴 타입, 매개변수 등을 기준으로 포인트컷 정의)
within 특정 클래스나 패키지 내의 메서드에 어드바이스 적용
args 메서드의 매개변수 타입을 기준으로 어드바이스 적용
@target 타겟 객체에 특정 애너테이션이 있을 경우에 어드바이스 적용
@within 클래스에 특정 애너테이션이 있을 경우에 어드바이스 적용
@annotation 메서드에 특정 애너테이션이 있을 경우에 어드바이스 적용
this 프록시 객체가 특정 타입을 구현한 경우에 어드바이스 적용
target 실제 타겟 객체가 특정 타입인 경우에 어드바이스 적용
bean 빈 이름을 기준으로 메서드 실행 지점을 필터링
@args 메서드의 매개변수에 특정 애너테이션이 적용된 경우에 어드바이스를 적용

스프링 핵심 원리 - 고급편 강의 | 김영한 - 인프런 강의 내용 참고

728x90