Spring
[Spring] Spring AOP로 Log 기록하기 : @Around / @Before / @After
s_ih_yun
2025. 9. 9. 23:46
728x90

1. Spring AOP
- AOP (Aspect-Oriented Programming) : 관점 지향 프로그래밍을 지원하는 기술
- 로깅, 보안, 트랜잭션 관리 등과 같은 공통 관심사를 모듈화
- 코드 중복을 줄이고 유지 보수성 향상
- 핵심 로직과 부가 기능 분리
1.1. 주요 용어
| 용어 | 설명 |
| Aspect | 공통적인 기능들을 모듈화한 것을 의미 |
| Target | Aspect가 적용될 대상 (메소드, 클래스 등이 해당) |
| Join point | Aspect가 적용될 수 있는 시점 (메소드 실행 전, 후 등) |
| Advice | Aspect의 기능을 정의한 것 |
| Point cut | Advice를 적용할 메소드의 범위를 지정 |
1.2. 주요 어노테이션
| 어노테이션 | 설명 |
| @Aspect | 해당 클래스를 Aspect로 사용하겠다는 명시 |
| @Before | 대상 메소드가 실행되기 전에 Advice 실행 |
| @AfterReturning | 대상 메소드가 정상적으로 실행되고 반환된 후 Advice 실행 |
| @AfterThrowing | 대상 메소드에서 예외가 발생했을 때 Advice 실행 |
| @After | 대상 메소드가 실행된 후에 Advice 실행 |
| @Around | 대상 메소드 실행 전, 후 또는 예외 발생 시 Advice 실행 |
2. Spring AOP로 Log 기록하기
2.1. Spring AOP 환경 설정
- build.gradle에 의존성 추가
dependencies {
implementation 'org.springframework.boot:spring-boot-starter-aop'
}
2.2. AOP 클래스 작성
2.2.1. @Before / @After : 메소드 호출 전 / 후 로깅
package com.syun.posleep.aspects;
import lombok.extern.slf4j.Slf4j;
import org.aspectj.lang.JoinPoint;
import org.aspectj.lang.annotation.*;
import org.springframework.stereotype.Component;
@Slf4j
@Aspect
@Component
public class ApiLoggingAspect {
@Pointcut("execution(* com.syun.posleep.web..*(..))") // 적용 범위 정의
public void controller() {
}
/* 메소드 호출 전 실행 */
@Before("controller()")
public void logBeforeTest(JoinPoint joinPoint) throws Throwable {
log.info("Controller Before");
}
/* 메소드 호출 후 실행 */
@After("controller()")
public void logAfterTest(JoinPoint joinPoint) throws Throwable {
log.info("Controller After");
}
}
- JoinPoint : Aspect가 적용될 시점을 의미
- 호출되는 대상 객체, 메서드, 전달 파라미터 목록에 접근 가능한 메서드 제공
- Log

2.2.2. @Around : 메소드 호출 전 / 후 / 예외상황 로깅
package com.syun.posleep.aspects;
import lombok.extern.slf4j.Slf4j;
import org.aspectj.lang.ProceedingJoinPoint;
import org.aspectj.lang.annotation.*;
import org.springframework.stereotype.Component;
@Slf4j
@Aspect
@Component
public class ApiLoggingAspect {
@Pointcut("execution(* com.syun.posleep.web..*(..))")
public void controller() {
}
@Around("controller()")
public Object logAroundTest(ProceedingJoinPoint joinPoint) throws Throwable {
log.info("Controller Before - Around"); // 메소드 호출 전
try {
Object result = joinPoint.proceed();
log.info("Controller Success - Around"); // 메소드 호출 후(성공)
return result;
} catch (Throwable e) {
log.info("!! Controller Fail - Around"); // 메소드 호출 후(예외발생)
throw e;
}
}
}
- Proceeding JoinPoint : JoinPoint를 상속 받아 추가 기능을 제공
- @Around에서만 지원
- proceed() 메소드를 통해 target 실행제어가 가능 (반드시 호출해야 타겟이 실행 가능)
- 반드시 Object를 리턴
- 타겟 메소드가 리턴하는 값을 그대로 반환
- void를 리턴타입으로 할 경우 : 타겟의 응답이 사라져 API가 동작하지 않음

📌 References
https://adjh54.tistory.com/133
https://velog.io/@youjung/Spring-AOP
https://velog.io/@jjeongdong/Spring-AOP를-활용한-Logging-구현
https://ivory-room.tistory.com/86
728x90