[AOP] Pointcut
by mignon25포인트컷(Pointcut)
- 조인 포인트 중에서 어드바이스가 적용될 위치를 선별하는 기능 (조인 포인트를 결정)
- 스프링 AOP 는 프록시 방식을 사용하므로 메서드 실행 지점만 포인트 컷으로 선별 가능
포인트컷 표현식(AspectJ pointcut expression)
- AspectJ가 제공하는 포인트컷 표현식
- Pointcut Designator : 포인트컷 지시자
// {} 안에 구성들이 바뀌는 부분
@{어드바이스}("{포인트컷지시자}{parameter}")
// 예시 : hello.hellospring 패키지의 하위에 모두 적용
@Around("execution(* hello.hellospring..*(..))")
포인트컷 지시자 (Pointcut Designator, PCD)
| 종류 | 설명 |
| execution | 메서드 실행 조인트 포인트를 매칭 스프링 AOP에서 가장 많이 사용하며, 기능도 복잡하다. |
| within | 특정 타입 내의 조인 포인트 매칭 |
| args | 인자가 주어진 타입의 인스턴스인 조인 포인트 |
| this | 스프링 빈 객체(스프링 AOP 프록시)를 대상으로 하는 조인 포인트 |
| target | Target 객체(스프링 AOP 프록시가 가리키는 실제 대상)를 대상으로 하는 조인 포인트 |
| @target | 실행 객체의 클래스에 주어진 타입의 애너테이션이 있는 조인 포인트 |
| @within | 주어진 애너테이션이 있는 타입 내 조인 포인트 |
| @annotation | 메서드가 주어진 애너테이션을 가지고 있는 조인 포인트를 매칭 |
| @args | 전달된 실제 인수의 런타임 타입이 주어진 타입의 애너테이션을 갖는 조인 포인트 |
| bean | 스프링 전용 포인트컷 지시자. 빈의 이름으로 포인트컷을 지정한다. |
execution
- 파라미터 값 표현형태가 특정 형식을 갖추고 있다.
=> 해당 조건에 만족하는 메서드에서만 AOP 실


// {} : 안의 값이 변경되는 부분
// ? : 보통 생략해서 사용
@{kind-of-Advice}("excution({modifiers-pattern}? {return-type-pattern} {declaring-type-pattern}? {method-name-pattern}({param-pattern}) {throws-pattern}?)")
// 예시
@Around("execution(public * start.aop.controller..*(..))")
- modifiers-pattern : 접근 제어자 지정 (public, private, *)
- return-type-pattern : 리턴 타입 지정 (void, String, *)
- declaring-type-pattern : (패키지 위치 필요)
- start.aop.controller.* : controller 패키지의 모든 클래스에 적용
- start.aop.controller.. : controller 패키지 및 하위 패키지의 모든 클래스에 적용
- method-name-pattern : 메서드 이름 지정
- addFolders : addFolders() 메서드에만 지정
- add* : add 로 시작하는 모든 메서드에 적용
- param-pattern : 특정 파라미터 지정
- ({특정 클래스 주소}) : 그 클래스/인터페이스가 파라미터인 메서드에 적용
- () : 인수 없음
- (*) : 인수 1개 (타입 상관없음)
- (..) : 인수, 타입 상관없음
포인트컷 표현식 사용 예제
@Pointcut(
"execution(" // PCD execution 지정
+ "[접근제한자 패턴] " // public
+ "리턴타입 패턴" // long
+ "[패키지명, 클래스 경로 패턴]" // com.moong.ahea.UserService
+ "메소드명 패턴(파라미터 타입 패턴|..)" // .findUserId(String)
+ "[throws 예외 타입 패턴]" // throws RuntimeException
+")"
)
// 모든 패키지에 포함된 클래스 중에, 클래스 이름이 Service로 끝나는 클래스
@Pointcut("execution( * *..*Service.findUserId(..) )")
// 최소한의 필수 규칙들 → 리턴타입 메소드명(파라미터)
@Pointcut("execution( * findUserId(..) )")
// find로 시작하는 메소드
@Pointcut("execution( * find*(..) )")
- 모든 공개 메서드 실행
- execution(public * *(..))
- 메서드 이름이 set 으로 시작하는 모든 메서드 실행
- execution(* set*(..))
- service 패키지에 정의된 메서드 실행
- execution(* com.xyz.service.*.*(..))
- 서비스 패키지 또는 하위 패키지의 모든 메서드 실행
- execution(* com.xyz.service..*.*(..))
- 서비스 패키지의 UserServiceImpl 클래스를 직접 지정, 해당 클래스의 모든 메서드 선택
- execution(* com.xyz.service.UserServiceImpl.*(..))
- 클래스 이름이 ServiceImpl로 끝나는 클래스의 모든 메서드 선택
- execution(* *..*ServiceImpl.*(..))
- hello 라는 이름을 가진 메서드 선정, 모든 파라미터 종류 허용
- execution(* hello(..))
- 패키지에 상관없이 Target 이라는 모든 클래스에 적용
- execution(* *..Target.*(..))
- 서비스 패키지 내의 모든 조인 포인트(only Spring AOP)
- within(com.xyz.service.*)
- 서비스 패키지 또는 하위 패키지 내의 모든 조인 포인트(only Spring AOP)
- within(com.xyz.service..*)
- AccountService 프록시가 인터페이스를 구현하는 모든 조인 포인트(only Spring AOP)
- this(com.xyz.service.AccountService)
- AccountService 대상 객체가 인터페이스를 구현하는 모든 조인 포인트 (only Spring AOP)
- target(com.xyz.service.AccountService)
- 단일 매개변수를 사용하고 런타임에 전달된 인수가 Serializable과 타입이 같은 모든 조인 포인트 (only Spring AOP)
- args(java.io.Serializable)
- 대상 객체에 @Transactional 애너테이션이 있는 모든 조인 포인트 (only Spring AOP)
- @target(org.springframework.transaction.annotation.Transactional)
- 실행 메서드에 @Transactional 애너테이션이 있는 조인 포인트(only Spring AOP)
- @annotation(org.springframework.transaction.annotation.Transactional)
- 단일 매개 변수를 사용하고 전달된 인수의 런타임 유형이 @Classified 애너테이션을 갖는 조인 포인트 (only Spring AOP)
- @args(com.xyz.security.Classified)
- tradeService 라는 이름을 가진 스프링 빈의 모든 조인 포인트 (only Spring AOP)
- bean(tradeService)
- 와일드 표현식 *Service 라는 이름을 가진 스프링 빈의 모든 조인 포인트
- bean(*Service)
포인트컷 표현식 결합
- && , || , !
- 포인트컷 표현식은 위의 3가지 연산자를 사용하여, PCD를 조합하여 사용할 수 있다.
- 조합할 때는, 포인트컷이 적용된 대상의 이름 사용
@Pointcut("execution(public * *(..))")
private void anyPublicOperation() {} // (1)
@Pointcut("within(com.xyz.myapp.trading..*)")
private void inTrading() {} // (2)
@Pointcut("anyPublicOperation() && inTrading()")
private void tradingOperation() {} // (3)
1. 접근 제한자 패턴이 public 인 모든 메서드에 적용
2. com.xyz.myapp.trading 패키지 및 하위 패키지의 모든 클래스의 모든 메서드에 적용
3. 1,2를 모두 만족시키는 모든 메서드에 적용
References
https://gmoon92.github.io/spring/aop/2019/05/06/pointcut.html
'Spring' 카테고리의 다른 글
| [AOP] Advice (0) | 2023.04.12 |
|---|---|
| [AOP] JoinPoint (0) | 2023.04.12 |
| 조회한 빈이 모두 필요할 때 - List, Map 사용 (0) | 2023.04.12 |
| @Autowired 사용할 때 빈 이름 중복 매칭 문제 - @Qualifier, @Primary (0) | 2023.04.11 |
| AOP의 용어 (0) | 2023.04.11 |
블로그의 정보
Mignon'S Dev Log
mignon25