스프링의 AOP는 프록시(Proxy) 방식으로 구현되며 Pointcut을 사용해 실행되는 메소드 범위 Joinpoint를 지정합니다.
스프링의 Pointcut 기본 문법
스프링에서는 AspectJ의 Pointcut 문법을 그대로 사용합니다. 기본적인 표현식에는 다음과 같은 규칙이 있습니다.
execution(<접근 지정자?> <반환 타입> <선언 타입?> <함수 이름><(파라미터)> <예외?>)
? 심볼은 생략 가능을 의미합니다. ? 심볼이 없으면 필수적으로 명시해야하는 구문입니다.
표현식에서 필수 구성만 포함하면 다음과 같이 축약됩니다.
execution(<반환 타입> <함수 이름><(파라미터)>)
스프링에서는 Pointcut의 접근 지정자로 public만 사용 할 수 있습니다.
- 그 외
protected | private | default는 사용 할 수 없습니다.
여러 가지 심볼을 사용해 표현식을 확장합니다.
*심볼은 매칭 가능한 모든 것을 의미합니다...심볼은 0개 이상 또는 하위 경로를 포함의 의미로 사용합니다.
execution은 Pointcut 지시자(PCD, Pointcut Designator)입니다. 모든 Pointcut 구문은 Designator로 시작합니다.
전체 PCD 유형은 docs.spring.io: Declaring a Pointcut(Supported Pointcut Designator)를 참고합니다.
execution 예시 1: 모든 Joinpoint와 매칭
프로젝트의 모든 함수와 매칭되도록 Joinpoint를 구성합니다.
@Pointcut("execution(* *(..))")
private void pointcutMethod() { }
구분 | 접근 지정자? | 반환 타입 | 선언 타입? | 함수 이름 | (파라미터) | 예외 ? |
구문 | 생략 | 생략 | 생략 | |||
비고 | 생략 | 모든 반환 타입과 매칭 | 생략 | 모든 함수 이름과 매칭 | 파라미터가 0개 이상과 매칭 | 생략 |
execution 예시 2: 지정된 Joinpoint와 매칭
프로젝트에서 유일한 함수와 매칭되도록 Joinpoint를 구성합니다.
@Pointcut("execution(public void com.io.test.HelloWord.helloworld(String, String))")
private void pointcutMethod() { }
구분 | 접근 지정자? | 반환 타입 | 선언 타입? | 함수 이름 | (파라미터) | 예외 ? |
구문 | 생략 | |||||
비고 | public 접근 지정자와 매칭 | void 반환 타입과 매칭 | com.io.test 패키지의 HelloWorld 클래스와 매칭 |
helloworld 함수 이름과 매칭 | 두 개의 String 파라미터와 매칭 | 예외 처리 없음 |
execution 예시 3: 특정 패키지 이하의 Joinpoint와 매칭
프로젝트의 특정 패키지 이하에서 실행되는 함수와 매칭되도록 Joinpoint를 구성합니다.
@Pointcut("execution(* com.io..*.*(..))")
private void pointcutMethod() { }
구분 | 접근 지정자? | 반환 타입 | 선언 타입? | 함수 이름 | (파라미터) | 예외 ? |
구문 | 생략 | 생략 | ||||
비고 | 생략 | 모든 반환 타입과 매칭 | com.io 패키지와 그 이하(..)의 모든 클래스(*.)와 매칭 |
모든 함수 이름과 매칭 | 파라미터가 0개 이상과 매칭 | 생략 |
within - 패키지, 클래스를 매칭하는 Designator
within을 사용하면 특정 클래스에 속하는 모든 함수를 Joinpoint로 구성합니다.
예를 들어 com.io.test 패키지의 HelloWolrd 클래스의 모든 함수와 Joinpoint를 구성하려면 다음과 같이 작성합니다.
@Pointcut("within(com.io.test.HelloWorld)")
private void pointcutMethod() { }
com.io.test 패키지의 모든 클래스가 실행하는 모든 함수와 Joinpoint를 구성합니다.
@Pointcut("within(com.io.test.*)")
private void pointcutMethod() { }
bean - Bean 이름과 매칭하는 Designator
bean을 사용하면 특정 Bean이 실행하는 모든 함수를 Joinpoint로 구성합니다.
예를 들어 hello로 시작하는 Bean 이름의 Bean이 실행하는 모든 함수와 Joinpoint를 구성 할 수 있습니다.
@Pointcut("bean(hello*)")
private void pointcutMethod() { }
bean은 스프링 2.5부터 사용 가능합니다.
Pointcut 표현식의 결합
여러 개의 Pointcut 표현식을 하나로 결합하여 Joinpoint를 구성 할 수 있습니다.
@Pointcut("execution(public * *(String, String)")
private void pointcutMethod0() { }
@Pointcut("within(com.io.test.*)")
private void pointcutMethod1() { }
코드 | 비고 | |
표현식을 결합하려면 AND(&&) OR(||) NOT(!)을 사용합니다.
&&를 사용하면 위 예시의 Pointcut의 조건을 모두 만족하는 새로운 Pointcut을 지정 할 수 있습니다.
@Pointcut("pointcutMethod0() && pointcutMethod1()")
private void combinedPointcutMethod() { }
@Pointcut에서는 다른 Pointcut의 표현식을 참조 할 수 있습니다.
예를 들어 다음 구문에서는 anotherPointcutMethod는 표현식을 직접 작성하는 대신 pointcutMethod0()의 표현식을 사용합니다.
@Pointcut("pointcutMethod0()")
private void anotherPointcutMethod() { }
이때 참조하는 함수의 접근 지정자가 중요합니다.
동일한 패키지에서는 소스가 되는 함수는 protected 또는 public으로 지정합니다. 다른 패키지에서는 소스가 되는 함수는 public으로 지정되어야 합니다.
정리 및 복습
- 스프링의 AOP는
프록시(Proxy)방식으로 구현되며Pointcut을 사용해 실행되는메소드 범위 Joinpoint를 지정합니다. 스프링에서는 AspectJ의 Pointcut 문법을 그대로 사용합니다. 기본적인 표현식에는 다음과 같은 규칙이 있습니다.
execution(<접근 지정자?> <반환 타입> <선언 타입?> <함수 이름><(파라미터)> <예외?>)
?심볼은 생략 가능을 의미합니다.?심볼이 없으면 필수적으로 명시해야하는 구문입니다.
execution(<반환 타입> <함수 이름><(파라미터)>)
*심볼은 매칭 가능한 모든 것을 의미합니다...심볼은 0개 이상 또는 하위 경로를 포함의 의미로 사용합니다.execution은Pointcut 지시자(PCD, Pointcut Designator)입니다.모든 Pointcut 구문은 Designator로 시작합니다.- 전체 PCD 유형은 docs.spring.io: Declaring a Pointcut(Supported Pointcut Designator)를 참고합니다.
withinPCD는특정 패키지와 클래스를 Joinpoint로 매칭합니다.beanPCD는특정 Bean 이름을 Joinpoint로 매칭합니다.- 여러 개의
Pointcut을 결합하여 표현식을 만들 수 있습니다. 구문으로는AND(&&)OR(||)NOT(!)을 사용합니다.
@Pointcut("pointcutMethod0() && pointcutMethod1()")
private void combinedPointcutMethod() { }
'Java > Spring' 카테고리의 다른 글
Spring 5 입문: Chapter 08A. JdbcTemplate을 사용한 DB 연동 (0) | 2023.12.05 |
---|---|
"Requested bean is currently in creation: Is there an unresolvable circular reference?" Bean 순환 참조 오류 (0) | 2023.12.04 |
Spring 5 입문: Chapter 07. AOP 프로그래밍(Aspect Oriented Programming) (0) | 2023.11.30 |
Spring 5 입문: Chapter 06. Bean 라이프사이클과 범위 (0) | 2023.11.28 |
"NoSuchBeanDefinitionException" Bean과 관련해서 자주 발생하는 오류 (0) | 2023.11.28 |