AspectJ의 Pointcut 표현식
AspectJ는 Pointcut을 명시할 수 있는 다양한 명시자를 제공하는데, 스프링은 메서드 호출과 관련된 명시자만을 지원하고 있다.
execution 명시자
execution명시자는 Advice를 적용할 메서드를 명시할 때 사용되며, 기본 형식은 다음과 같다.
execution(수식어패턴? 리턴타입패턴 클래스이름패턴?메서드이름패턴(파라미터패턴)
"수식어패턴" 부분은 생략 가능한 부분으로서 public, protected 등이 올 수 있는데 스프링은 public 메서드에만 적용 가능하기 때문에 사실상 public 이외의 값은 의미가 없다.
각 패턴은 "*"을 이용하여 모든 값을 표현할 수 있다. 또한, ".."을 이용하여 0개 이상이라는 의미를 표현할 수 있다.
예시를 살펴보자.
execution(public void set*(..))
리턴 타입이 void이고 메서드 이름이 set으로 시작하고, 파라미터가 0개 이상인 메서드 호출. 파라미터 부분에 ".."을 사용하여 파라미터가 0개 이상인 것을 표현하였다.
execution(* com.mypackage.*.*())
com.mypackage 패키지의 파라미터가 없는 모든 메서드 호출
execution(* com.mypackage..*.*(..))
com.mypackage 패키지 및 하위 패키지에 있는, 파라미터가 0개 이상인 모든 메서드 호출. 패키지 부분에 ".."을 사용하여 해당 패키지 또는 하위 패키지를 표현하였다.
execution(Integer com.mypackage.board.WriteArticleService.write(..))
리턴 타입이 Integer인 WriteArticleService 인터페이스의 write() 메서드 호출
execution(* get*(*))
이름이 get으로 시작하고 1개의 파라미터를 갖는 메서드 호출
execution(* get*(*, *))
이름이 get으로 시작하고 2개의 파라미터를 갖는 메서드 호출
execution(* read*(Integer, ..))
메서드 이름이 read로 시작하고, 첫 번째 파라미터 타입이 Integer이며, 1개 이상의 파라미터를 갖는 메서드 호출
within 명시자
within 명시자는 특정 타입에 속하는 메서드를 Pointcut으로 설정할 때 사용된다.
예시를 살펴보자.
within(com.mypackage.board.WriteArticleService)
WriteArticleService 인터페이스의 모든 메서드 호출
within(com.mypackage.board.*)
com.mypackage.board 패키지에 있는 모든 메서드 호출
within(com.mypackage.board..*)
com.mypackage.board 패키지 및 그 하위 패키지에 있는 모든 메서드 호출
bean 명시자
bean 명시자는 스프링에서 추가적으로 제공하는 명시자로서, 스프링 빈 이름을 이용하여 Pointcut을 정의한다. bean 명시자는 빈 이름의 패턴을 갖는다.
예시를 살펴보자.
bean(writeArticleService)
이름이 writeArticleService인 빈의 메서드 호출
bean(*ArticleService)
이름이 ArticleService로 끝나는 빈의 메서드 호출
Pointcut의 조합
각각의 표현식은 "&&" 또는 "||" 연산자를 이용하여 연결할 수 있다.
예시를 살펴보자.
@AfterThrowing(pointcut="execution(public * get*()) && execution(public void set*(..))")
public void throwing() {
// 이하 생략
...
}
@Aspect 어노테이션을 이용하는 경우 "&&" 연산자를 사용하여 두 표현식을 모두 만족하는 JoinPoint에만 Advice가 적용되도록 할 수 있다.
<aop:pointcut id="propertyMethod"
expression="execution(public * get*()) && execution(public void set*(..))"
/>
XML 스키마를 이용하여 "&&" 연산자를 사용했는데 XML 문서는 "&&"를 "&&"로 표현하였다. 이는 불편하므로 스프링 설정 파일에서 "and"와 "or"를 사용할 수 있도록 하고 있다. 따라서 다음과 같이 입력할 수 있다.
<aop:pointcut id="propertyMethod"
expression="execution(public * get*()) and execution(public void set*(..))"
/>
@Pointcut 어노테이션을 사용하는 경우 메서드 이름을 이용해서 쉽게 두 개 이상의 Pointcut을 조합할 수 있다.
@Pointcut("execution(public * *(..))")
private void publicMethod() {}
@Pointcut("within(com.mypackage.board..*)")
private void inBoard() {}
@Pointcut("publicMethod() && inBoard()")
private void boardPublicOperation() {}
@Pointcut 어노테이션을 이용하면 XML 스키마를 이용하는 경우에 비해 Pointcut의 조합 및 자새용이 쉽기 때문에 공통으로 사용되는 Pointcut은 @Pointcut 어노테이션을 이용해서 표현하는 것이 좋다.
Reference
- 웹 개발자를 위한 Spring 4.0 프로그래밍 (최범균 저)
'Spring' 카테고리의 다른 글
| [Spring] 스프링 MVC(2) - DispatcherServlet 설정 (0) | 2022.03.12 |
|---|---|
| [Spring] 스프링 MVC(1) - 기본 흐름과 구성 요소 (0) | 2022.03.12 |
| [Spring] 스프링 AOP(6) - Proxy Target Class (0) | 2022.02.20 |
| [Spring] 스프링 AOP(5) - JoinPoint (0) | 2022.02.19 |
| [Spring] 스프링 AOP(4) - @Pointcut 어노테이션 (0) | 2022.02.19 |