*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 속성에 발생한 예외를 저장할 변수 이름을 지정 |
'스프링(Spring)' 카테고리의 다른 글
예외처리 (0) | 2022.12.27 |
---|---|
스프링 트랜잭션과 로깅 (0) | 2022.12.05 |
Dynamic SQL (MyBatis 동적 SQL), AOP(Aspect Oriented Programming) (0) | 2022.11.02 |
MyBatis 소개, Mapper XML 파일 (0) | 2022.10.27 |
Spring-Data Access, DataSource, Servlet Context, Context 분리와 전략 (0) | 2022.10.19 |