실행 위치 비교

3줄 요약

  • Filter, Interceptor, AOP는 모두 공통 처리를 분리하지만 실행 위치가 다르다.
  • Filter는 Servlet Container와 DispatcherServlet 사이, Interceptor는 Spring MVC 핸들러 실행 전후, AOP는 Spring Bean 메서드 호출 전후에 붙는다.
  • 무엇을 쓸지는 “HTTP 요청 자체를 다루는가, MVC 핸들러 흐름을 다루는가, Bean 메서드 정책을 다루는가”로 판단한다.

핵심 정리

  • Filter는 가장 앞단에서 요청과 응답을 감싼다. 인코딩, CORS, 보안, 요청 로깅, compression처럼 Servlet 레벨의 관심사에 맞다.
  • HandlerInterceptor는 DispatcherServlet이 Handler를 찾은 뒤 Controller 실행 전후에 개입한다. 인증보다는 MVC 요청 맥락, locale, 공통 model, 핸들러 기반 로깅에 어울린다.
  • AOP는 HTTP와 무관하게 Spring Bean 메서드 실행을 감싼다. 트랜잭션, 서비스 성능 측정, 감사 로그, 권한 정책 같은 메서드 경계 정책에 맞다.
  • Spring 공식 문서도 Interceptor를 보안 계층으로 쓰는 것을 권장하지 않는다. path matching 차이와 MVC 경계 때문에 보안은 Spring Security나 Servlet FilterChain에 통합된 방식이 더 안전하다.
  • 세 도구는 경쟁 관계가 아니라 서로 다른 경계의 도구다. 같은 로깅이라도 access log는 Filter, handler 정보 로그는 Interceptor, service method timing은 AOP가 더 자연스럽다.
  • 선택 기준은 기술 선호가 아니라 필요한 정보와 실행 위치다.

헷갈리는 지점

  • 공통 처리는 전부 AOP로 빼면 된다고 생각하기 쉽다. AOP가 횡단 관심사 분리에 특화되어 보이기 때문이다.
    • 핵심은 AOP가 Spring Bean 메서드 호출 경계에 강하고 원시 HTTP 요청 앞단에는 맞지 않을 수 있다는 점이다.
    • 요청 body, CORS, Servlet response 조작은 Filter나 MVC 계층이 더 직접적이다.
  • Interceptor와 Filter를 같은 것으로 보기 쉽다. 둘 다 요청 전후에 실행되기 때문이다.
    • 핵심은 Filter는 DispatcherServlet 이전 Servlet 경계이고 Interceptor는 HandlerMapping 이후 MVC 경계라는 점이다.
    • Handler 정보가 필요하면 Interceptor, Controller 도착 전 보안/프로토콜 처리가 필요하면 Filter를 먼저 본다.
  • Security도 Interceptor로 만들 수 있다고 생각하기 쉽다. URL별 접근 제어처럼 보이기 때문이다.
    • 핵심은 Spring Security가 Filter 기반으로 Controller 이전에 동작한다는 점이다.
    • 인증/인가, CSRF, CORS, 예외 진입점은 Security FilterChain에서 다루는 것이 표준 흐름이다.

확인 질문

  • Filter, Interceptor, AOP의 가장 큰 차이는 무엇인가?
    • 실행 위치와 사용할 수 있는 컨텍스트가 다르다.
  • Handler 정보가 필요한 MVC 공통 처리는 무엇이 적합한가?
    • HandlerInterceptor가 적합하다.
  • Service 메서드 실행 시간을 공통 측정하려면 무엇이 적합한가?
    • Spring AOP가 적합하다.

Servlet Filter

3줄 요약

  • Servlet Filter는 DispatcherServlet보다 앞에서 요청과 응답을 감싸는 표준 Servlet 구성요소다.
  • Filter는 chain.doFilter(request, response)를 호출해 다음 필터나 Servlet으로 요청을 넘긴다.
  • Spring Security는 이 Filter 계층에 연결되어 인증, 인가, CSRF, CORS, 예외 처리를 Controller 이전에 수행한다.

핵심 정리

  • Filter는 Spring MVC와 무관하게 Servlet Container 레벨에서 실행된다.
  • 요청이 Controller까지 가지 않아도 Filter는 실행될 수 있다.
  • Filter는 원시 ServletRequest, ServletResponse를 다루므로 HTTP header, body wrapper, status, redirect, error response를 직접 제어할 수 있다.
  • Spring Security의 실제 보안 필터들은 Servlet Container에 각각 직접 등록되는 것이 아니라 FilterChainProxy 안의 SecurityFilterChain으로 관리된다.
  • OncePerRequestFilter는 Spring에서 한 요청당 한 번 실행되는 Filter 구현을 만들 때 자주 쓰는 기반 클래스다.
  • Filter 순서는 매우 중요하다. 인증 정보를 만드는 Filter는 권한 판단 Filter보다 앞에 있어야 한다.

헷갈리는 지점

  • Filter도 Spring Bean이니 MVC Handler 정보를 쉽게 알 수 있다고 생각하기 쉽다. 같은 애플리케이션 안에서 동작하기 때문이다.
    • 핵심은 Filter는 HandlerMapping 이전에 실행된다는 점이다.
    • 어떤 Controller 메서드가 실행될지는 아직 결정되지 않았을 수 있다.
  • chain.doFilter()를 항상 마지막에 호출하면 된다고 생각하기 쉽다. 예제가 그렇게 보이는 경우가 많기 때문이다.
    • 핵심은 호출 전후가 각각 전처리와 후처리 위치라는 점이다.
    • 호출하지 않으면 뒤 필터와 DispatcherServlet으로 요청이 넘어가지 않는다.
  • JWT Filter를 아무 위치에 추가해도 된다고 생각하기 쉽다. 토큰만 읽으면 된다고 느끼기 때문이다.
    • 핵심은 JWT 검증으로 Authentication을 만든 뒤 인가 필터가 그 정보를 사용해야 한다는 점이다.
    • Security 필터 순서 안에서 적절한 위치를 선택해야 한다.

확인 질문

  • Filter는 DispatcherServlet보다 앞에서 실행되는가?
    • 그렇다. Servlet FilterChain은 DispatcherServlet 호출 전에 실행된다.
  • chain.doFilter()를 호출하지 않으면 어떻게 되는가?
    • 요청이 다음 필터나 Servlet으로 넘어가지 않고 현재 Filter에서 흐름이 멈춘다.
  • Spring Security가 Filter 계층을 사용하는 이유는 무엇인가?
    • Controller 이전에 인증, 인가, CSRF, CORS, 예외 처리를 수행해야 하기 때문이다.

HandlerInterceptor

3줄 요약

  • HandlerInterceptor는 Spring MVC가 Handler를 찾은 뒤 Controller 실행 전후에 개입한다.
  • preHandle, postHandle, afterCompletion으로 Controller 전, View 렌더링 전, 요청 완료 후 처리를 나눌 수 있다.
  • Interceptor는 Handler 정보가 필요한 MVC 공통 처리에 적합하지만 보안의 주력 도구로 쓰기에는 한계가 있다.

핵심 정리

  • Interceptor는 DispatcherServlet 내부 MVC 흐름의 확장 지점이다.
  • preHandle은 Controller 호출 전에 실행되며 false를 반환하면 이후 처리를 중단할 수 있다.
  • postHandle은 Controller가 반환한 뒤 View 렌더링 전에 실행된다. REST 응답에서는 기대와 다를 수 있다.
  • afterCompletion은 요청 완료 후 실행되며 예외 발생 여부를 확인할 수 있다.
  • Interceptor는 HandlerMethod 정보에 접근할 수 있어 특정 애너테이션, Controller 타입, 경로별 로깅에 유용하다.

헷갈리는 지점

  • Interceptor가 Filter보다 항상 더 Spring답다고 생각하기 쉽다. MVC와 더 가까워 보이기 때문이다.
    • 핵심은 MVC Handler가 결정된 뒤에야 동작한다는 점이다.
    • Controller 이전 보안과 프로토콜 레벨 처리는 Filter가 더 앞선 위치에 있다.
  • Interceptor를 API 응답 body 후처리에 쓰기 쉽다고 생각하기 쉽다. Controller 뒤에 실행된다고 배웠기 때문이다.
    • 핵심은 response body 변환은 MessageConverter 흐름과 연결되어 있어 Interceptor가 본문 변경에 적합하지 않을 수 있다는 점이다.
    • 응답 body 변환은 ResponseBodyAdvice 같은 도구가 더 맞을 수 있다.
  • Interceptor로 인증을 구현하면 충분하다고 보기 쉽다. preHandle에서 막을 수 있기 때문이다.
    • 핵심은 인증/인가, SecurityContext, 예외 entry point, CSRF 같은 보안 흐름은 Spring Security FilterChain이 표준이라는 점이다.
    • Interceptor는 보안 보조 정보나 MVC 맥락 처리가 필요할 때 제한적으로 쓴다.

확인 질문

  • HandlerInterceptor는 어느 시점에 실행되는가?
    • DispatcherServlet이 Handler를 찾은 뒤 Controller 실행 전후에 실행된다.
  • afterCompletion은 언제 실행되는가?
    • 요청 처리가 완료된 뒤 실행되며 예외 정보를 확인할 수 있다.
  • Interceptor가 Filter보다 더 적합한 상황은 무엇인가?
    • HandlerMethod나 MVC handler 정보가 필요한 공통 처리 상황이다.

AOP 프록시

3줄 요약

  • AOP는 HTTP 요청 흐름이 아니라 Spring Bean 메서드 호출 흐름에 적용된다.
  • 트랜잭션, 캐싱, 서비스 성능 측정, 감사 로그처럼 메서드 경계 정책을 분리할 때 적합하다.
  • 내부 호출, Bean이 아닌 객체, final 제약 같은 프록시 한계를 이해하지 못하면 적용 여부를 잘못 판단한다.

핵심 정리

  • Spring AOP는 프록시 기반으로 외부에서 Bean 메서드를 호출할 때 Advice를 실행한다.
  • AOP는 Controller, Service, Repository처럼 Spring Bean 메서드 실행에 붙을 수 있지만 Servlet Filter처럼 요청의 가장 앞단을 감싸지는 않는다.
  • HTTP header나 raw request body를 직접 다루는 요구에는 AOP보다 Filter나 MVC 확장점이 적합하다.
  • 서비스 메서드의 실행 시간, 트랜잭션, 재시도, 감사 로그, 권한 검사처럼 비즈니스 메서드 경계 정책에는 AOP가 잘 맞는다.
  • AOP는 호출 흐름을 숨길 수 있으므로 적용 범위와 Pointcut을 좁고 명확하게 유지해야 한다.

헷갈리는 지점

  • AOP가 가장 고급 도구이니 모든 공통 처리에 우선이라고 생각하기 쉽다. 횡단 관심사라는 표현이 넓기 때문이다.
    • 핵심은 횡단 관심사라도 어느 경계를 가로지르는지 봐야 한다는 점이다.
    • HTTP 요청 경계면 Filter, MVC Handler 경계면 Interceptor, Bean 메서드 경계면 AOP가 자연스럽다.
  • Controller 메서드에 AOP를 붙이면 Security Filter를 대체할 수 있다고 생각하기 쉽다. Controller 호출 전후 제어가 가능해 보이기 때문이다.
    • 핵심은 보안 요청이 Controller까지 도달하지 않을 수도 있다는 점이다.
    • 인증/인가의 표준 경계는 Security FilterChain이다.
  • AOP가 적용되지 않으면 Pointcut만 틀렸다고 보기 쉽다. 표현식 실수가 흔하기 때문이다.
    • 핵심은 프록시를 통과한 Spring Bean 외부 호출인지 먼저 확인하는 것이다.
    • self-invocation, 직접 생성 객체, final 메서드도 원인이 될 수 있다.

확인 질문

  • AOP는 어떤 경계에 가장 적합한가?
    • Spring Bean 메서드 실행 경계에 가장 적합하다.
  • HTTP 요청 body를 원시 상태로 감싸야 한다면 무엇이 더 적합한가?
    • Servlet Filter나 request wrapper가 더 적합하다.
  • AOP 적용 여부를 볼 때 Pointcut 외에 확인할 것은 무엇인가?
    • 호출이 Spring AOP 프록시를 통과하는지, Bean인지, 내부 호출인지 확인해야 한다.