Post

02 Spring AOP

02 Spring AOP

1. AOP

1. AOP

  • 핵심 로직과 공통 관심사(Cross-Cutting Concern)를 분리하는 프로그래밍 기법
    • 핵심 로직(Core Business Logic): 실제 애플리케이션이 수행하는 기능
    • 횡단 관심사(Cross-Cutting Concern): 로깅, 트랜잭션, 보안, 성능 측정 등 여러 곳에서 반복되는 코드

2. 구성요소

구성 요소설명
Aspect공통 관심 사항을 모듈화한 단위 (ex: 로그, 트랜잭션)
AdviceAspect 내에서 실행될 코드 (Before, After, Around 등)
실행 되는 코드와 타이밍
Join pointAdvice가 적용될 수 있는 지점 (메서드 실행, 예외 발생 등)
어떤 메소드에서 advice를 실행할 것 인가?
PointcutAdvice를 적용할 Join point를 지정하는 표현식
Target핵심 비즈니스 로직이 있는 객체
WeavingAspect와 Target을 연결하는 과정 (컴파일, 클래스 로딩, 런타임)

2. AOP 사용

1. 어드바이스 종류

Advice 종류실행 시점내용예시 코드
Before메서드 실행 전메서드 실행 전에 수행, 주로 로깅, 권한 체크, 입력 검증@Before(“execution(* com.example.service..(..))”)
public void logBefore(JoinPoint jp) { }
After Returning메서드 정상 종료 후메서드 결과 값 사용 가능, 성공 후 처리@AfterReturning(pointcut=”execution(* com.example.service..(..))”, returning=”result”)
public void logAfterReturn(Object result) { }
After Throwing메서드 예외 발생 시예외 처리, 로깅 등에 사용@AfterThrowing(pointcut=”execution(* com.example.service..(..))”, throwing=”ex”)
public void logException(Exception ex) { }
After (Finally)메서드 종료 후 항상정상/예외 관계없이 항상 실행@After(“execution(* com.example.service..(..))”)
public void logAfter() { }
Around메서드 실행 전/후메서드 실행 전후 모두 처리 가능, 결과 조작 가능, proceed() 호출 필수@Around(“execution(* com.example.service..(..))”)
public Object logAround(ProceedingJoinPoint pjp) throws Throwable {
System.out.println(“전”);
Object res = pjp.proceed();
System.out.println(“후”);
return res;
}
  • Before → Around → AfterReturning/AfterThrowing → After(Finally)

1. execution

1. execution

  • execution = 메서드 실행(join point)을 패턴으로 선택하는 지시자
  • execution(접근제어자 반환타입 패키지.클래스.메서드(매개변수))

2. execution 사용

위치의미예시
접근제어자public, private 등 (생략 가능)public
반환타입리턴 타입, * 가능void, *
클래스/패키지적용 대상 클래스, 패키지com.example.service.CarService
메서드메서드 이름, * 가능drive, *
매개변수파라미터 타입, .. = 0개 이상(), (..), (String, ..)

3. exectuion 예시

예시의미적용 대상
execution(* com.example.CarService.drive(..))특정 클래스의 특정 메서드CarService 클래스의 drive() 메서드, 매개변수 개수와 타입 무관
execution(* com.example.CarService.*(..))특정 클래스의 모든 메서드CarService 클래스 내 모든 메서드
execution(* com.example.service.*.*(..))특정 패키지 모든 클래스, 모든 메서드com.example.service 패키지 내 모든 클래스, 모든 메서드
execution(String com.example.CarService.getName(..))특정 반환타입 메서드반환 타입이 StringCarService 클래스의 getName() 메서드
execution(public void com.example.CarService.start(String))접근제어자 + 반환타입 + 매개변수 지정public, 반환 void, 매개변수 String 1개인 start() 메서드
execution(* com.example..*Service.*(..))와일드카드 + 하위 패키지com.example 패키지와 하위 패키지의 *Service 클래스 모든 메서드

3. 포인트컷 표현식(pointcut expression)

1. 포인트컷

  • @Pointcut을 쓰는 이유 = 여러 Advice에서 재사용 가능 + 가독성/유지보수 편리
  • 포인트컷을 안쓰고 어드바이스에 execution을 넣어도 문제없음.

2. 예시s

1
2
3
4
5
6
7
8
9
// 포인트컷 사용
@Pointcut("execution(* com.example.service.*.*(..))")
public void serviceMethods() { }

@Before("serviceMethods()")
public void logBefore() { }

@After("serviceMethods()")
public void logAfter() { }
1
2
@Before("execution(* com.example.service.*.*(..))")
public void logBefore() { }
This post is licensed under CC BY 4.0 by the author.