오늘은 Spring MVC 중 Servlet / Container / Filter / Interceptor를 “어디에서 동작하는가?” 기준으로 정리해보겠습니다.
이는 인증/인가, 로깅, 트랜잭션(@Transactional) 같은 주제가 전부 같은 뿌리에서 이해됩니다.
0. 전체 큰 그림
[클라이언트]
↓
[서블릿 컨테이너(Tomcat)]
↓
[Filter] ===> 서블릿 컨테이너 레벨에서 동작. (DispatcherServlet 이전)
↓
[DispatcherServlet]
↓
[Interceptor] ===> Spring MVC레벨에서 동작. (Controller 전후)
↓
[Controller]
↓
[Service(@Transactional)]
↓
[Repository(JPA)]
↓
[DB]
여기서 눈여겨 볼 것은 아래와 같습니다.
1. [Filter] ===> 서블릿 컨테이너 레벨에서 동작. (DispatcherServlet 이전)
2. [Interceptor] ===> Spring MVC레벨에서 동작. (Controller 전후)
1. Servlet이란?
HTTP 요청을 처리하는 자바 객체입니다.
원래 서블릿만으로 웹을 만들면 개발자가 아래를 직접 처리해야 했습니다.
- 요청 파라미터/헤더/바디 파싱
- 응답 상태코드/헤더/바디 생성
- 객체 생명주기 관리
- 동시에 여러 요청이 오면 스레드 안전성 고려
2. Servlet Container(Tomcat 등)란?
서블릿을 “운영”해주는 실행 환경입니다. 개발자가 하기 어려운 부분을 컨테이너가 대신합니다.
컨테이너가 하는 대표 역할은 아래와 같습니다.
- 요청을 받기 (네트워크/HTTP 처리)
- 적절한 서블릿을 실행 (서블릿 인스턴스 + 스레드 관리)
- 응답을 클라이언트로 돌려주기
3. Filter와 Interceptor 차이
동작하는 위치(레벨)가 다르다.
필터 :
- Spring을 모름.
- 요청/응답을 통째로 전처리/후처리하기 좋음
- “스프링에 들어오기 전에” 필요한 공통 작업에 적합
✅ Filter에서 주로 하는 일
- 인코딩 설정
- CORS 처리
- JWT 인증/인가(초기 차단)
- 요청/응답 로깅
- XSS 방어
- 추적 ID(Request ID) 부여
✅ 왜 Filter가 필요할까요?
Filter는 스프링으로 들어오면 안 되는 요청을 초기에 잘라내기에 강합니다.
예를 들어 “토큰이 아예 없는 요청”을 컨트롤러까지 보내고 나서 막는 것보다,
Filter에서 바로 401로 차단하는 방식이 더 자연스럽습니다.
Interceptor는 Spring MVC 레벨
Interceptor는 DispatcherServlet 이후, Controller 실행 전/후에 있습니다.
✅ 특징
- Spring 컨텍스트 접근 가능 (스프링 빈을 쓸 수 있음)
- “어떤 컨트롤러/메서드로 가는 요청인지”를 알고 동작할 수 있음
- 세밀한 제어에 유리
✅ Interceptor에서 주로 하는 일
- 로그인 체크(컨트롤러별로 정책 다르게)
- 권한 검사(특정 API만 허용)
- 컨트롤러 실행 전/후 로깅
- 요청 처리 시간 측정(핸들러 단위)
- 사용자 컨텍스트 세팅(예: 사용자 정보 주입)
정리
✅ Filter를 쓰면 좋은 경우
- “스프링에 들어오기 전에” 막아야 하는 요청
예) 토큰 없으면 바로 차단, CORS 처리, 인코딩 처리, 전역 로깅
✅ Interceptor를 쓰면 좋은 경우
- “어떤 컨트롤러로 가는지 보고” 판단해야 할 때
예) 특정 API만 로깅, API별 권한 정책, 컨트롤러 전/후 공통 처리
Filter는 컨테이너에서 먼저 걸러주는 장치이고, Interceptor는 스프링 MVC 안에서 컨트롤러를 기준으로 세밀하게 제어하는 장치입니다.
'Spring' 카테고리의 다른 글
| [Spring] Spring WebFlux와 Spring MVC - 1 (0) | 2026.02.11 |
|---|---|
| [Spring] controller에서 repository를 참조하는 코드를 짜면? (0) | 2026.02.02 |
| [Spring] 컨테이너가 빈을 생성하는 과정 (0) | 2026.01.29 |
| [Spring] IoC, DI (0) | 2026.01.28 |
| [Spring/JPA] @Transactional을 활용한 엔티티 수정 방식 비교 (0) | 2026.01.19 |