Spring
> [AOP] 3. 포인트컷(PointCut)의 다양한 표현식
1z
2022. 10. 27. 10:52

■
1. 포인트컷
advice 가 실행되는 시점을 제어한다.
(1) 사용법
1. 포인트컷 표현식은 @Pointcut 어노테이션의 값으로 나타낸다.
@Pointcut("within(@org.springframework.stereotype.Repository *)")
public void repositoryClassMethods() {}Copy
2. pointcut signature : advice 어노테이션이 해당 포인트 컷의 메소드명을 참조한다.
@Around("repositoryClassMethods()")
public Object measureMethodExecutionTime(ProceedingJoinPoint pjp) throws Throwable {
...
}Copy
(2) 명시자
| 종류 | 설명 |
| execution | Advice를 적용할 메서드를 명시 할 때 사용 |
| within | 타입 패턴 내에 속하는 메서드를 JoinPoint로 설정되도록 명시할 때 사용 |
| bean | 스프링 빈을 이용하여 JoinPoint를 설정 (스프링 2.5 부터 지원) |
(3) 리턴타입 지정
// server.spring.aop 패키지에 속해있고, 파라미터가 1개인 모든 메서드
@Pointcut("execution(public Integer server.spring.aop.*.*(*))")
| 표현식 | 설명 |
| * | 모든 리턴타입 허용 |
| void | 리턴타입이 void인 메소드 선택 |
| !void | 리턴타입이 void가 아닌 메소드 선택 |
(4) 패키지 지정
| 표현식 | 설명 |
| server.spring.service | 정확하게 server.spring.service 패키지만 선택 |
| server.spring.domain.. | server.spring.domain 패키지로 시작하는 모든 패키지 선택 |
(5) 클래스 지정
// server.spring 패키지 및 하위 패키지에 속해있고, 이름이 Service르 끝나는 인터페이스의 파라미터가 0개 이상인 모든 메서드
@Pointcut("execution(* server.spring..*Service.*(..))")
| 표현식 | 설명 |
| User | 정확하게 User 클래스만 선택 |
| *DTO | 이름이 DTO 로 끝나는 클래스만 선택 |
| BaseDTO+ | 클래스 이름 뒤에 '+'가 붙으면 해당 클래스로부터 파생된 모든 자식 클래스 선택, 인터페이스 이름 뒤에 '+'가 붙으면 해당 인터페이스를 구현한 모든 클래스 선택 |
(6) 메소드 지정
// 메서드 이름이 do 시작하고 파라미터가 2개인 모든 메서드
@Pointcut("execution(* do*(*, *))")
// server.spring 패키지 및 하위 패키지에 속해있고, 이름이 get으로 시작하는 파라미터가 0개 이상인 모든 메서드
@Pointcut("execution(* server.spring..*.get*(..))")
| 표현식 | 설명 |
| *(..) | 모든 메소드 선택 |
| update*(..) | 메소드명이 update로 시작하는 모든 메소드 선택 |
(7) 파라미터 지정
// find로 시작하고 Long 유형의 매개변수가 하나만 있는 모든 메소드
@Pointcut("execution(* *..find*(Long))")
// 매개변수 수에 관계없지만, Long 유형의 첫 번째 매개변수를 가진 메소드
@Pointcut("execution(* *..find*(Long,..))")
| 표현식 | 설명 |
| (..) | 타입에 무관한 0개 이상의 매개변수 |
| (*) | 반드시 1개의 매개변수를 가지는 메소드만 선택 |
| (server.spring.domain.user.model.User) | 매개변수로 User를 가지는 메소드만 선택. 꼭 풀패키지명이 있어야함 |
| (!server.spring.domain.user.model.User) | 매개변수로 User를 가지지않는 메소드만 선택 |
| (Integer, ..) | 한 개 이상의 매개변수를 가지되, 첫번째 인수는 Integer 타입으로 시작하고 나머지는 타입 무관 |
| (Integer, *) | 반드시 두 개의 매개변수를 가지되, 첫 번째 매개변수의 타입이 Integer인 메소드만 선택 |
■
2. execution 명시자
execution ([접근제한자 패턴] [리턴 타입] [타입패턴 .] [이름패턴](파라미터 타입) [throws 예외패턴 ])
execution(* aspects.trace.demo.*.*(..))
1. 접근 제한자 패턴 : public, private 등 (생략 가능)
2. 리턴타입
3. 타입 패턴 : 패키지와 클래스 이름에 대한 패턴, '.'을 사용해 연결한다. (클래스 이름은 풀 패키지명으로 명시. 생략 가능)
4. 이름 패턴 : 메서드 이름 패턴
5. 파라미터 : 파라미터의 타입패턴. 와일드 카드를 이용해 파라미터의 개수에 상관없는 패턴을 만들 수 있다.
▶ 와일드 카드
@Pointcut("execution(* server.spring.service.BoardService.*(..))")
- 첫 번째 와일드 카드: 모든 반환 값과 일치
- 두 번째 와일드 카드: 모든 메서드 이름과 일치
- 세 번째 와일드 카드: (..) => 모든 타입의 파라미터 0개 이상
■
3. within 명시자
// com.baeldung 패키지나 하위 패키지 내의 모든 유형과 일치
@Pointcut("within(com.baeldung.pointcutadvice.dao.FooDao)")
// com.baeldung 패키지나 하위 패키지 내의 모든 유형과 일치
@Pointcut("within(com.baeldung..*)")
// server.spring 패키지의 모든 메서드
@Pointcut("within(server.spring*)")
■
4. bean 명시자
// bean 이름이 userService 인 빈의 모든 메서드
@Pointcut("bean(userService)")
// bean 이름이 user 으로 시작하는 빈의 모든 메서드
@Pointcut("bean(user*)")
■
4. 포인트컷 표현식 결합
&& , || , !
@Pointcut("@target(org.springframework.stereotype.Repository)")
public void repositoryMethods() {}
@Pointcut("execution(* *..create*(Long,..))")
public void firstLongParamMethods() {}
@Pointcut("repositoryMethods() && firstLongParamMethods()")
public void entityCreationMethods() {}
참고
https://sjh836.tistory.com/157
https://icarus8050.tistory.com/8
https://www.baeldung.com/spring-aop-pointcut-tutorial
https://docs.spring.io/spring-framework/reference/core/aop/ataspectj/pointcuts.html