Spring AOP에서는 AspectJ 스타일의 어노테이션을 사용하여 AOP 기능을 간편하게 적용할 수 있습니다.
다음은 주요 어노테이션과 그 역할에 대한 설명입니다.
@Aspect - 애스펙트 정의import org.aspectj.lang.annotation.Aspect;
import org.springframework.stereotype.Component;
@Aspect
@Component
public class LoggingAspect {
// Advice(공통 기능)를 여기에 추가
}
@Pointcut - AOP 적용 대상 지정Advice에서 재사용할 수 있습니다.import org.aspectj.lang.annotation.Pointcut;
@Pointcut("execution(* com.example.service.*.*(..))")
public void serviceMethods() {} // service 패키지의 모든 메서드가 대상
🔹 execution() 표현식
@Pointcut("execution(반환타입 패키지명.클래스명.메서드명(매개변수))")
| 표현식 예제 | 의미 |
|---|---|
execution(* com.example..*(..)) | com.example 패키지 이하 모든 메서드 적용 |
execution(* com.example.service.UserService.getUser(..)) | UserService.getUser() 메서드만 적용 |
execution(public * *(..)) | 모든 public 메서드 적용 |
@Before - 메서드 실행 이전에 실행import org.aspectj.lang.annotation.Before;
import org.aspectj.lang.annotation.Aspect;
import org.springframework.stereotype.Component;
@Aspect
@Component
public class LoggingAspect {
@Before("execution(* com.example.service.*.*(..))")
public void beforeAdvice() {
System.out.println("[로그] 메서드 실행 전");
}
}
@After - 메서드 실행 후에 실행import org.aspectj.lang.annotation.After;
@Aspect
@Component
public class LoggingAspect {
@After("execution(* com.example.service.*.*(..))")
public void afterAdvice() {
System.out.println("[로그] 메서드 실행 후");
}
}
@AfterReturning - 메서드가 정상적으로 실행된 후 실행import org.aspectj.lang.annotation.AfterReturning;
@Aspect
@Component
public class LoggingAspect {
@AfterReturning(pointcut = "execution(* com.example.service.*.*(..))", returning = "result")
public void afterReturningAdvice(Object result) {
System.out.println("[로그] 정상 실행 완료. 반환 값: " + result);
}
}
@AfterThrowing - 메서드 실행 중 예외가 발생했을 때 실행import org.aspectj.lang.annotation.AfterThrowing;
@Aspect
@Component
public class LoggingAspect {
@AfterThrowing(pointcut = "execution(* com.example.service.*.*(..))", throwing = "ex")
public void afterThrowingAdvice(Exception ex) {
System.out.println("[예외 발생] " + ex.getMessage());
}
}
@Around - 메서드 실행 전후로 감싸기import org.aspectj.lang.annotation.Around;
import org.aspectj.lang.ProceedingJoinPoint;
@Aspect
@Component
public class LoggingAspect {
@Around("execution(* com.example.service.*.*(..))")
public Object aroundAdvice(ProceedingJoinPoint joinPoint) throws Throwable {
long start = System.currentTimeMillis();
System.out.println("[로그] 메서드 실행 시작");
Object result = joinPoint.proceed(); // 실제 메서드 실행
System.out.println("[로그] 메서드 실행 완료");
long executionTime = System.currentTimeMillis() - start;
System.out.println("[로그] 실행 시간: " + executionTime + "ms");
return result;
}
}
| 어노테이션 | 설명 | 실행 시점 |
|---|---|---|
@Aspect | 클래스가 AOP 기능을 포함하는 Aspect 임을 선언 | - |
@Pointcut | 특정 메서드를 AOP 적용 대상으로 설정 | - |
@Before | 메서드 실행 전에 실행 | 메서드 실행 전 |
@After | 메서드 실행 후 (예외 발생 여부 관계없음) | 메서드 실행 후 |
@AfterReturning | 메서드가 정상 실행된 후 실행 | 정상 실행 후 |
@AfterThrowing | 메서드 실행 중 예외 발생 시 실행 | 예외 발생 시 |
@Around | 메서드 실행 전후를 감싸서 실행 | 전, 후, 예외 발생 시 |
@Before → 메서드 실행 전 @After → 메서드 실행 후 (예외 여부 상관없음) @AfterReturning → 메서드 정상 종료 후 @AfterThrowing → 메서드 실행 중 예외 발생 시 @Around → 메서드 실행 전, 후, 예외 처리까지 모두 가능 Spring AOP의 어노테이션을 적절히 활용하면 비즈니스 로직과 공통 관심사를 분리할 수 있어 코드 유지보수가 쉬워집니다. 🚀