스프링 AOP에서 포인트컷(Pointcut) 표현식은 특정 조건에 따라 어드바이스(Advice)가 적용될 메서드를 필터링하는 데 사용됩니다. 포인트컷 표현식을 통해 클래스나 메서드 이름, 매개변수, 접근 제어자 등에 따라 어드바이스가 적용될 메서드를 지정할 수 있습니다.
스프링 AOP에서 포인트컷 표현식을 작성하는 기본 문법을 한글로 정리하겠습니다. 포인트컷 표현식은 특정 조건을 설정해 어드바이스가 실행될 메서드를 선택할 수 있게 해주는 문법입니다.
1. execution - 메서드 실행 시점을 기준으로 필터링
메서드의 이름, 접근 제어자, 리턴 타입, 매개변수 타입 등을 기준으로 특정 메서드에 어드바이스를 적용할 때 사용됩니다.
기본 문법
execution(접근제어자 리턴타입 클래스명.메서드명(파라미터타입))
예시
- execution(* com.example.service.*.*(..))
- com.example.service 패키지에 있는 모든 클래스의 모든 메서드에 적용.
- execution(public * *(..))
- 접근제어자가 public인 모든 메서드에 적용.
- execution(* set*(..))
- set으로 시작하는 모든 메서드에 적용.
2. within - 특정 클래스나 패키지 내에서 필터링
특정 패키지나 클래스에 속한 메서드들에 어드바이스를 적용할 때 사용됩니다.
기본 문법
within(패키지명.클래스명)
예시
- within(com.example.service.*)
- com.example.service 패키지 내의 모든 클래스에 적용.
- within(com.example.service..*)
- com.example.service 패키지와 그 하위 패키지에 있는 모든 클래스에 적용.
- within(com.example.MyClass)
- com.example.MyClass 클래스 내의 모든 메서드에 적용.
3. args - 메서드의 파라미터 타입을 기준으로 필터링
특정 타입의 파라미터를 가지는 메서드에 어드바이스를 적용할 때 사용됩니다.
기본 문법
args(파라미터 타입)
예시
- args(String)
- 파라미터가 String 타입인 메서드에 적용.
- args(String, ..)
- 첫 번째 파라미터가 String 타입이고, 이후 임의의 파라미터를 가지는 메서드에 적용.
4. @annotation - 특정 어노테이션이 적용된 메서드에 필터링
특정 어노테이션이 붙은 메서드에 어드바이스를 적용할 때 사용됩니다.
기본 문법
@annotation(어노테이션 타입)
예시
- @annotation(org.springframework.transaction.annotation.Transactional)
- @Transactional 어노테이션이 붙은 메서드에만 적용.
5. @within - 특정 어노테이션이 클래스 레벨에 적용된 경우 필터링
특정 어노테이션이 클래스에 적용된 경우, 그 클래스의 모든 메서드에 어드바이스를 적용합니다.
기본 문법
@within(어노테이션 타입)
예시
- @within(org.springframework.stereotype.Service)
- @Service 어노테이션이 붙은 클래스의 모든 메서드에 적용.
6. @target - 특정 어노테이션이 적용된 빈의 메서드에 필터링
특정 어노테이션이 붙은 빈의 모든 메서드에 어드바이스를 적용합니다.
기본 문법
@target(어노테이션 타입)
예시
- @target(org.springframework.stereotype.Repository)
- @Repository 어노테이션이 붙은 빈의 모든 메서드에 적용.
7. @args - 특정 어노테이션이 붙은 파라미터를 가지는 메서드에 필터링
파라미터 중 특정 어노테이션이 붙은 인자를 가진 메서드에 어드바이스를 적용합니다.
기본 문법
@args(어노테이션 타입)
예시
- @args(org.springframework.stereotype.Repository)
- 파라미터에 @Repository 어노테이션이 붙은 인자를 가진 메서드에 적용.
포인트컷 조합 연산자
포인트컷 표현식은 &&(AND), ||(OR), !(NOT) 연산자를 사용하여 조합할 수 있습니다.
- AND (&&): 두 조건을 모두 만족할 때 적용
- 예시: execution(* com.example..*(..)) && @annotation(org.springframework.transaction.annotation.Transactional)
- OR (||): 두 조건 중 하나라도 만족할 때 적용
- 예시: within(com.example.service.*) || within(com.example.repository.*)
- NOT (!): 특정 조건을 제외할 때 사용
- 예시: execution(* com.example..*(..)) && !within(com.example.excluded.*)
참조 문서
- Spring 공식 문서 (영문): Spring AOP Documentation
- AspectJ 문법 공식 가이드 (영문): AspectJ Language Reference
주요 포인트컷 표현식 요소
- execution: 메서드 실행을 기반으로 어드바이스를 적용하는 가장 일반적인 표현식입니다. 메서드 이름, 리턴 타입, 파라미터 타입 등을 기준으로 필터링할 수 있습니다.
- 표현식: execution(modifiers-pattern? ret-type-pattern declaring-type-pattern? name-pattern(param-pattern) throws-pattern?)
- 예시:
- execution(* com.example.service.*.*(..)): com.example.service 패키지 내의 모든 클래스에 속한 메서드에 적용.
- execution(public * *(..)): 접근제어자가 public인 모든 메서드에 적용.
- execution(* set*(..)): set으로 시작하는 모든 메서드에 적용.
- within: 특정 타입에 속한 메서드에 어드바이스를 적용합니다.
- 표현식: within(type-pattern)
- 예시:
- within(com.example.service.*): com.example.service 패키지 내의 모든 클래스에 적용.
- within(com.example.service..*): com.example.service 패키지와 하위 패키지의 모든 클래스에 적용.
- args: 메서드의 파라미터 타입에 따라 어드바이스를 적용합니다.
- 표현식: args(argument-pattern)
- 예시:
- args(String): String 타입의 인자를 받는 메서드에 적용.
- args(String, ..): 첫 번째 파라미터가 String 타입이고, 이후 임의의 인자가 있는 메서드에 적용.
- @annotation: 특정 어노테이션이 적용된 메서드에 어드바이스를 적용합니다.
- 표현식: @annotation(annotation-type)
- 예시:
- @annotation(org.springframework.transaction.annotation.Transactional): @Transactional이 붙은 메서드에만 적용.
- @within: 특정 어노테이션이 클래스 레벨에 적용된 경우, 해당 클래스의 모든 메서드에 어드바이스를 적용합니다.
- 표현식: @within(annotation-type)
- 예시:
- @within(org.springframework.stereotype.Service): @Service가 적용된 클래스의 모든 메서드에 적용.
- @target: 특정 어노테이션이 붙은 빈의 모든 메서드에 어드바이스를 적용합니다.
- 표현식: @target(annotation-type)
- 예시:
- @target(org.springframework.stereotype.Repository): @Repository가 붙은 모든 빈의 메서드에 적용.
- @args: 인수에 특정 어노테이션이 적용된 메서드에 어드바이스를 적용합니다.
- 표현식: @args(annotation-type, ..)
- 예시:
- @args(org.springframework.stereotype.Repository): 인수로 @Repository 어노테이션이 있는 메서드에 적용.
포인트컷 표현식 조합
포인트컷 표현식은 && (AND), || (OR), ! (NOT) 논리 연산자를 통해 조합할 수 있습니다.
- AND: 두 조건을 모두 만족하는 경우 적용됩니다.
- 예시: execution(* com.example.service.*.*(..)) && @annotation(org.springframework.transaction.annotation.Transactional)
- OR: 두 조건 중 하나라도 만족하는 경우 적용됩니다.
- 예시: within(com.example.service.*) || within(com.example.repository.*)
- NOT: 특정 조건을 제외하고 적용합니다.
- 예시: execution(* com.example..*(..)) && !within(com.example.excluded.*)
스프링 AOP 포인트컷 표현식 예시
@Aspect
@Component
public class LoggingAspect {
// 특정 메서드 이름을 가진 메서드들에 대해 Advice 적용
@Before("execution(* com.example.service.*.find*(..))")
public void logBeforeFindMethods() {
System.out.println("메서드 시작 전 로그...");
}
// 특정 어노테이션이 붙은 메서드에만 적용
@Around("@annotation(org.springframework.transaction.annotation.Transactional)")
public Object logTransactionalMethods(ProceedingJoinPoint joinPoint) throws Throwable {
System.out.println("트랜잭션 메서드 실행 전...");
Object result = joinPoint.proceed();
System.out.println("트랜잭션 메서드 실행 후...");
return result;
}
}
'Backend > Spring' 카테고리의 다른 글
| SpringBoot : Logging (0) | 2024.11.19 |
|---|---|
| Spring Application 이벤트 리스너 (0) | 2024.11.19 |
| Spring AOP (0) | 2024.11.19 |
| @Autowired (1) | 2024.11.15 |
| Bean Scope (0) | 2024.11.15 |