
Filter, Interceptor, AOP는 모두 요청을 처리하는 과정과 관련이 있다. Filter, Interceptor, AOP가 적용된 스프링프레임워크가 외부에서 요청이 왔을 때 처리하는 흐름은 아래처럼 요약할 수 있다.
HTTP 요청
↓
[Filter] — 서블릿 컨테이너 단계
↓
DispatcherServlet
↓
[Interceptor: preHandle]
↓
Controller
↓
[Interceptor: postHandle]
↓
ViewResolver → View Rendering
↓
[Interceptor: afterCompletion]
↓
HTTP 응답

Filter는 javax.servlet의 표준 기술로,DispatcherServlet에 요청이 전달되기 전/후에 url 패턴에 맞는 요청에 대해 부가 작업을 처리할 수 있는 기능을 제공한다.
DispatcherServlet?
클라이언트의 요청을 받아 적절한 컨트롤러로 전달하고 처리 결과를 다시 뷰로 전달하는 프론트 컨트롤러를 말한다.
스프링 컨테이너가 아닌 웹 컨테이너에 의해 관리되는 것이며, DispatfherServlet 전/후에 처리하는 것이다.
DispatcherServlet이 실행되기 전 요청을 가로채서 요청 인코딩을 적용하고 요청 시간과 Request ID에 대해 로그를 남기는 코드이다.
import jakarta.servlet.*;
import jakarta.servlet.http.HttpServletRequest;
import java.io.IOException;
import java.util.UUID;
public class RequestLoggingFilter implements Filter{
@Override
public void doFilter(ServletRequest request, ServletResponse response, FilterChain chain) throws IOException, ServletException{
request.setCharacterEncoding("UTF-8");
HttpServletRequest http = (HttpServletRequest) request;
String rid = UUID.randomUUID().toString();
long start = System.currentTimeMillis();
try {
// MDC 등에 넣어서 로그 상관관계 추적 가능
http.setAttribute("RID", rid);
chain.doFilter(request, response); // 다음으로
} finally {
long took = System.currentTimeMillis() - start;
System.out.printf("[Filter] %s %s rid=%s took=%dms%n",
http.getMethod(), http.getRequestURI(), rid, took);
}
}
}
이후 스프링 부트에서 등록하면 된다.
import org.springframework.boot.web.servlet.FilterRegistrationBean;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
@Configuration
public class FilterConfig {
@Bean
public FilterRegistrationBean<RequestLoggingFilter> requestLoggingFilter() {
FilterRegistrationBean<RequestLoggingFilter> reg = new FilterRegistrationBean<>();
reg.setFilter(new RequestLoggingFilter());
reg.addUrlPatterns("/*");
reg.setOrder(1); // 낮을수록 먼저
return reg;
}
}

Interceptor는 Spring MVC 라이브러리 중 하나로 DispatcherServlet이 컨트롤러를 호출하기 전과 후에 요청 응답을 참조하거나 가공할 수 있는 기능을 제공한다. Interceptor는 스프링 컨테이너 내에서 동작하기에 필터를 거쳐 DispatcherServlet이 요청을 받은 이후에 동작하게 된다.
컨트롤러 실행 전 후에 로그를 찍고 응답 직전에 모델에 공통 데이터를 추가하는 인터셉터 코드이다.
import org.springframework.lang.Nullable;
import org.springframework.web.method.HandlerMethod;
import org.springframework.web.servlet.HandlerInterceptor;
import org.springframework.web.servlet.ModelAndView;
import jakarta.servlet.http.HttpServletRequest;
import jakarta.servlet.http.HttpServletResponse;
public class HandlerLoggingInterceptor implements HandlerInterceptor {
@Override
public boolean preHandle(HttpServletRequest req, HttpServletResponse res, Object handler) {
if (handler instanceof HandlerMethod hm) {
String ctrl = hm.getBeanType().getSimpleName();
String method = hm.getMethod().getName();
System.out.printf("[Interceptor:pre] %s#%s %s%n", ctrl, method, req.getRequestURI());
}
// false를 리턴하면 체인 중단 (컨트롤러 호출되지 않음)
return true;
}
@Override
public void postHandle(HttpServletRequest req, HttpServletResponse res, Object handler,
@Nullable ModelAndView mav) {
if (mav != null) {
mav.addObject("globalNotice", "서비스 점검 02:00~03:00");
}
System.out.println("[Interceptor:post] view=" + (mav != null ? mav.getViewName() : "null"));
}
@Override
public void afterCompletion(HttpServletRequest req, HttpServletResponse res, Object handler, Exception ex) {
if (ex != null) {
System.out.println("[Interceptor:afterCompletion] exception=" + ex.getMessage());
}
System.out.println("[Interceptor:afterCompletion] done");
}
}
이후에 Interceptor를 등록해주고 경로 패턴을 설정해준다.
import org.springframework.context.annotation.Configuration;
import org.springframework.web.servlet.config.annotation.*;
@Configuration
public class WebMvcConfig implements WebMvcConfigurer {
@Override
public void addInterceptors(InterceptorRegistry reg) {
reg.addInterceptor(new HandlerLoggingInterceptor())
.addPathPatterns("/**")
.excludePathPatterns(
"/css/**", "/js/**", "/images/**", "/favicon.ico",
"/actuator/**", "/health"
);
// 등록 순서가 호출 순서에 영향
}
}
| 구분 | Servlet Filter | Spring Interceptor |
|---|---|---|
| 소속 | Servlet 표준 기술 (javax.servlet) | Spring MVC 구성 요소 |
| 동작 시점 | DispatcherServlet 이전/이후 | DispatcherServlet 이후 |
| 적용 범위 | 모든 요청 (정적 리소스 포함) | 컨트롤러 요청에 한정 |
| 접근 가능 데이터 | Request, Response | Handler, Model, View |
| 등록 방법 | web.xml / FilterRegistrationBean | WebMvcConfigurer#addInterceptors |
| 주로 사용 | 인코딩, 로깅, CORS, 보안 | 인증, 로깅, 모델 가공 |