T_era
API 로깅 Interceptor VS AOP 본문
API를 로깅하기 위한 방법을 알아보면서 알게된 Interceptor와 AOP의 주요 사용처와 차이점을 찾아보게 되었다
1. Interceptor
정의:
- Spring MVC의 요청 처리 과정에서 특정 URL 패턴에 대해 요청을 가로채서 처리하는 컴포넌트
- HandlerInterceptor 인터페이스를 구현하여 사용
주요 사용 시점:
public class CustomInterceptor implements HandlerInterceptor {
@Override
public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler) {
// 컨트롤러 실행 전
return true; // true면 api 호출 계속 진행, false면 중단
}
@Override
public void postHandle(HttpServletRequest request, HttpServletResponse response, Object handler, ModelAndView modelAndView) {
// 컨트롤러 실행 후, 뷰 렌더링 전
}
@Override
public void afterCompletion(HttpServletRequest request, HttpServletResponse response, Object handler, Exception ex) {
// 뷰 렌더링 후
}
}
주요 사용 사례:
- 인증/인가 처리
- 로깅
- CORS 처리
- 요청/응답 데이터 변환
- 공통 예외 처리
장점:
- Spring MVC의 요청 처리 파이프라인에 자연스럽게 통합
- URL 패턴 기반의 필터링이 용이
- HTTP 요청/응답 객체에 직접 접근 가능
- 가볍고 성능이 좋음
단점:
- 메서드 단위의 세밀한 제어가 어려움
- 비즈니스 로직과의 결합도가 높을 수 있음
2. AOP (Aspect-Oriented Programming)
정의:
- 관심사를 분리하여 모듈화하는 프로그래밍 패러다임
- @Aspect 어노테이션을 사용하여 구현
주요 사용 시점:
@Aspect
@Component
public class CustomAspect {
@Before("execution(* com.example.service.*.*(..))")
public void beforeAdvice(JoinPoint joinPoint) {
// 메서드 실행 전
}
@After("execution(* com.example.service.*.*(..))")
public void afterAdvice(JoinPoint joinPoint) {
// 메서드 실행 후
}
@Around("@annotation(Loggable)")
public Object aroundAdvice(ProceedingJoinPoint joinPoint) throws Throwable {
// 메서드 실행 전후
return joinPoint.proceed();
}
}
주요 사용 사례:
- 트랜잭션 관리
- 로깅
- 성능 모니터링
- 예외 처리
- 캐싱
장점:
- 메서드 단위의 세밀한 제어 가능
- 비즈니스 로직과 완전히 분리
- 재사용성이 높음
- 다양한 조인포인트 지원 (메서드 실행, 예외 발생 등)
단점:
- 런타임에 프록시가 생성되어 약간의 성능 오버헤드
- 디버깅이 어려울 수 있음
- HTTP 요청/응답 객체에 직접 접근이 어려움
3. 선택 가이드
Interceptor를 선택하는 경우:
- HTTP 요청/응답 레벨의 처리가 필요할 때
- URL 패턴 기반의 필터링이 필요할 때
- 인증/인가와 같은 보안 관련 처리
- CORS, 캐시 컨트롤 등 HTTP 관련 처리
AOP를 선택하는 경우:
- 메서드 단위의 세밀한 로깅이 필요할 때
- 트랜잭션 관리가 필요할 때
- 비즈니스 로직과 완전히 분리된 공통 기능이 필요할 때
- 성능 모니터링이나 캐싱이 필요할 때
4. 실제 사용 예시
Interceptor 예시 (인증 처리):
@Component
public class AuthInterceptor implements HandlerInterceptor {
@Override
public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler) {
String token = request.getHeader("Authorization");
if (token == null || !isValidToken(token)) {
response.setStatus(HttpServletResponse.SC_UNAUTHORIZED);
return false;
}
return true;
}
}
AOP 예시 (로깅):
@Aspect
@Component
public class LoggingAspect {
@Around("@annotation(Loggable)")
public Object logMethod(ProceedingJoinPoint joinPoint) throws Throwable {
String methodName = joinPoint.getSignature().getName();
log.info("Method {} started", methodName);
Object result = joinPoint.proceed();
log.info("Method {} finished", methodName);
return result;
}
}
5. 결론
- Interceptor: HTTP 요청/응답 레벨의 처리에 적합
- AOP: 비즈니스 로직 레벨의 처리에 적합
- 두 기술을 함께 사용하여 각각의 장점을 활용하는 것도 좋은 방법
- 프로젝트의 요구사항과 특성에 따라 적절한 기술을 선택하는 것이 중요
'Programing > Spring' 카테고리의 다른 글
| 테스트 코드 mock()과 ReflectionTestUtils (0) | 2025.06.09 |
|---|---|
| 테스트 코드 어노테이션 및 메서드 정리 (0) | 2025.06.09 |
| N+1 문제와 페치 조인 적용해 해결하기 (1) | 2025.06.02 |
| 좋아요 기능과 동시성 문제? (0) | 2025.06.02 |
| 스프링 시큐리티 인증 및 인가 흐름 (0) | 2025.05.26 |