스프링(Spring)

PointCut 표현식과 Advisor 구현

개발학생 2022. 11. 20. 15:41
반응형

*22년 4월 한 달간 한국이러닝협회의 '실전 개발자를 위한 Spring Framework'를 수강하고 정리한 내용입니다

*모든 이미지의 출처는 한국이러닝협회의 '전 개발자를 위한 Spring Framework'에 있습니다

 

 

1. PointCut 표현식

1) 문법

- AspectJ 포인트컷 표현식은 포인트컷 지시자를 이용하여 작성함

- 포인트컷 지시자 중 가장 대표적으로 사용되는 것은 execution()

- execution() 지시자를 사용한 포인트컷 표현식의 문법구조는 다음과 같음

//[접근제한자 패턴]: public, private과 같은 접근제한자 (생략가능)
//타입패턴[타입패턴.]: 앞의 타입패턴은 리턴값의 타입패턴이고, 뒤의 타입패턴은 패키지와 클래스 이름에 대한 패턴(생략가능, 사용할때 '.'을 사용해연결함)
//(타입패턴|"..",...): "타입패턴"은 메소드 이름 타입패턴. 파라미터의 타입 패턴을 순서대로 넣을 수 있다. 또한, 와일드카드를 이용해 파라미터 개수에 상관없는 패턴을 만들 수 있다
execution( [접근제한자 패턴] 타입패턴 [타입패턴.] 이름패턴 (타입패턴 | "..", ...) 

//예외이름패턴
[throws 예외패턴])

 

2) 예시

//aspects 앞의 *: Any return type을 넣는자리
//trace: 패키지
//*.*: 클래스.메소드
//(..): Any type and number of arguments가 들어갈 자리
execution(* aspects.trace.demo.*.*(..))

(1) execution(* hello(..))

- hello라는 이름을 가진 메소드를 선정하는 것

- 모든 종류의 파라미터 허용

 

(2) execution(* hello())

- 파라미터 패턴이 ()이므로, hello 메소드 중 파라미터가 없는 것만 선택

 

(3) execution(* myspring.user.service.UserServiceImpl.*(..))

- myspring.user.service.UserServiceImpl 클래스를 직접 지정하여, 이 클래스가 가진 모든 메소드 선택

 

(4) execution(* myspring.user.service.*.*(..))

- myspring.user.service 패키지의 모든 클래스에 적용됨 (But, 서브패키지의 클래스는 포함 X)

 

(5) execution(* myspring.user.service..*.*(..))

- myspring.user.service 패키지의 모든 클래스에 적용됨 (서브패키지의 모든 클래스 포함)

 

(6) execution(* *..Target.*(..))

- 패키지에 상관없이 Target이라는 이름의 모든 클래스에 적용됨 (주의: 다른 패키지에 같은 이름의 클래스가 있어도 적용됨)

 

2. Advisor 구현

1) Spring AOP 구현

(1) XML 기반의 POJO 클래스를 이용한 구현

- 부가기능을 제공하는 Advice 클래스 작성

- XML 설정 파일에 <aop:config>를 이용해서 aspect를 설정 (=advice와 pointcut 설정)

 

(2) @Aspect 어노테이션을 이용한 구현

- @Aspect 어노테이션을 이용해서 부가기능을 제공하는 Aspect 클래스 작성
   (Aspect 클래스는 advice를 구현하는 메소드와 pointcut을 포함)

- XML 설정 파일에 <aop:aspectj-autoproxy />를 설정

 

*Aspect 어노테이션

- Aspect 클래스 선언 시 @Aspect 어노테이션 사용 (AspectJ 5버전에 새롭게 추가된 어노테이션)

- 이 어노테이션을 이용할 경우, 클래스 내부에 advice와 pointcut을 정의할 수 있음

- <aop:aspectj-autoproxy> 태그를 XML 설정파일에 추가하면, @Aspect 어노테이션이 적용된 Bean을 Aspect로 사용가능

 

2) Advice

(1) JoinPoint 인터페이스 - AOP가 적용되는 지점

- 모든 어드바이스는 org.aspectj.lang.JoinPoint 타입의 파라미터를 어드바이스 메소드에 첫 번째 매개변수로 선언 가능

- Around 어드바이스는 JoinPoint의 하위 클래스인 ProceedingJoinPoint 타입의 파라미터를 필수적으로 선언해야 함

 

*주요 메소드

getArgs() 메소드 arguement 반환
getThis() 프록시 객체 반환
getTarget() 대상 객체 반환
getSignature() advice되는 메소드의 description 반환
toString() advice되는 메소드의 설명 출력

 

*JoinPoint 인터페이스 예시

 

*ProceedingJoinPoint 인터페이스 예시

 

(2) Advice의 종류

Around 어드바이스 - Joinpoint 앞과 뒤에서 실행되는 Advice
- 타깃의 메소드가 호출되기 이전(before) 시점과 이후(after) 시점에 모두 처리해야 하는 부가기능 정의
Before 어드바이스 - Jointpoint 앞에서 실행되는 Advice
- 타깃의 메소드가 실행되기 이전(before) 시점에 처리해야 하는 부가기능 정의
After Returning 어드바이스 - Jointpoint 메소드 호출이 정상적으로 종료된 후 실행되는 Advice
- 타깃의 메소드가 정상적으로 실행된 이후(after) 시점에 처리해야 하는 부가기능 정의
After Throwing 어드바이스 - 예외가 던져질 때 실행되는 Advice
- 타깃의 메소드가 예외를 발생시킨 이후(after) 시점에 처리해야 하는 부가기능 정의

 

(3) Advice를 정의하기 위한 어노테이션

@Before("pointcut") - 타깃 객체의 메소드가 실행되기 전에 호출되는 어드바이스
- JoinPoint를 통해 파라미터 정보를 참조할 수 있음
@After("pointcut") - 타깃 객체의 메소드 정상 종료/예외가 발생 시 모두 호출되는 어드바이스
- 리턴값이나 예외를 직접 전달받을 순 없음
@Around("pointcut") - 타깃 객체의 메소드가 호출되는 전 과정을 모두 담을 수 있는 어드바이스
- 가장 강력한 기능을 가진 어드바이스
@AfterReturning(pointcut="",returning="") - 타깃 객체의 메소드가 정상적으로 실행을 마친 후 호출되는 어드바이스
- 리턴값 참조 시, return 속성에 리턴값을 저장할 수 있는 변수 이름을 지정
@AfterThrowing(pointcut="",throwing="") - 타깃 객체의 메소드가 예외가 발생하면 호출되는 어드바이스
- 발생한 예외 참조 시, throwing 속성에 발생한 예외를 저장할 변수 이름을 지정

 

반응형