Spring Boot에서 Filter, Interceptor, AOP 사용법 정리하기

안녕하세요! 이번 글에서는 Spring Boot 애플리케이션에서 자주 사용되는 세 가지 기술, Filter, Interceptor, 그리고 AOP의 개념과 사용법을 정리해 보려고 합니다. 이 기술들은 각각 요청 처리 과정의 특정 시점에 로직을 삽입하는 역할을 하지만, 적용되는 계층과 방식에 차이가 있습니다. 어떤 상황에서 어떤 기술을 사용해야 할지 명확히 이해하는 데 도움이 될 거예요. 😊


 

1. Filter (필터)

 

필터Servlet 영역에서 동작하며, 모든 요청이 컨트롤러에 도달하기 전에 공통적으로 처리해야 할 작업을 수행할 때 사용됩니다. 웹 애플리케이션의 가장 앞단에 위치하기 때문에, 여러 컨트롤러에 걸쳐 반복되는 로직을 구현하기에 적합합니다.

 

주요 용도

 

  • 보안 및 인증: 로그인 여부 확인, JWT 토큰 유효성 검사
  • 로깅: 모든 요청에 대한 로그 기록
  • 인코딩: 문자 인코딩 설정
  • XSS 방어: SQL 인젝션, XSS 공격 방어 로직

 

사용법

 

javax.servlet.Filter 인터페이스를 구현하여 필터를 정의합니다. doFilter() 메서드 내에 로직을 작성하고, chain.doFilter()를 호출하여 다음 필터나 서블릿으로 요청을 전달해야 합니다.

Java

import javax.servlet.*;
import java.io.IOException;

public class CustomFilter implements Filter {

    @Override
    public void doFilter(ServletRequest request, ServletResponse response, FilterChain chain) throws IOException, ServletException {
        // 요청 처리 전 로직
        System.out.println("Filter: 요청이 들어왔습니다.");

        // 다음 필터로 요청 전달
        chain.doFilter(request, response);

        // 요청 처리 후 로직
        System.out.println("Filter: 요청 처리가 완료되었습니다.");
    }
}

필터를 등록하려면 @Component 어노테이션을 사용하거나, FilterRegistrationBean을 통해 수동으로 등록할 수 있습니다.

Java

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<CustomFilter> customFilter() {
        FilterRegistrationBean<CustomFilter> registrationBean = new FilterRegistrationBean<>();
        registrationBean.setFilter(new CustomFilter());
        registrationBean.addUrlPatterns("/api/*"); // 필터를 적용할 URL 패턴
        return registrationBean;
    }
}

 

2. Interceptor (인터셉터)

 

인터셉터Spring MVC 영역에서 동작하며, Dispatcher Servlet이 컨트롤러를 호출하기 전후에 작업을 가로채는 역할을 합니다. HandlerInterceptor 인터페이스를 구현하며, 필터보다 더 세밀하게 요청을 제어할 수 있습니다.

 

주요 용도

 

  • 로그인 체크: 특정 핸들러(컨트롤러) 실행 전 로그인 여부 확인
  • 권한 체크: 특정 페이지나 기능에 대한 접근 권한 확인
  • 성능 측정: 컨트롤러 실행 시간 측정
  • API 호출 로깅: 특정 API에 대한 상세 로그 기록

 

사용법

 

HandlerInterceptor 인터페이스를 구현하고, preHandle(), postHandle(), afterCompletion() 메서드를 재정의하여 로직을 작성합니다.

  • preHandle(): 컨트롤러 실행 전 호출됩니다. true를 반환하면 다음 단계로 진행하고, false를 반환하면 요청 처리가 중단됩니다.
  • postHandle(): 컨트롤러 실행 후 View 렌더링 직전에 호출됩니다.
  • afterCompletion(): View 렌더링이 완료된 후, 요청 처리의 모든 과정이 끝난 뒤에 호출됩니다.

Java

import org.springframework.web.servlet.HandlerInterceptor;
import org.springframework.web.servlet.ModelAndView;

import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;

public class CustomInterceptor implements HandlerInterceptor {

    @Override
    public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler) throws Exception {
        System.out.println("Interceptor: 컨트롤러 실행 전");
        return true; // 계속 진행
    }

    @Override
    public void postHandle(HttpServletRequest request, HttpServletResponse response, Object handler, ModelAndView modelAndView) throws Exception {
        System.out.println("Interceptor: 컨트롤러 실행 후");
    }

    @Override
    public void afterCompletion(HttpServletRequest request, HttpServletResponse response, Object handler, Exception ex) throws Exception {
        System.out.println("Interceptor: View 렌더링 완료 후");
    }
}

인터셉터는 WebMvcConfigurer를 구현한 설정 클래스에서 addInterceptors() 메서드를 오버라이드하여 등록합니다.

Java

import org.springframework.context.annotation.Configuration;
import org.springframework.web.servlet.config.annotation.InterceptorRegistry;
import org.springframework.web.servlet.config.annotation.WebMvcConfigurer;

@Configuration
public class WebConfig implements WebMvcConfigurer {

    @Override
    public void addInterceptors(InterceptorRegistry registry) {
        registry.addInterceptor(new CustomInterceptor())
                .addPathPatterns("/api/**"); // 인터셉터를 적용할 URL 패턴
    }
}

 

3. AOP (Aspect-Oriented Programming, 관점 지향 프로그래밍)

 

AOP는 **OOP(객체 지향 프로그래밍)**를 보완하는 개념으로, 애플리케이션의 여러 부분에 **흩어져 있는 공통 기능(횡단 관심사)**을 한 곳에 모아 관리하는 기술입니다. Spring AOP는 프록시 패턴을 기반으로 구현됩니다.

 

주요 용어

 

  • Aspect (애스펙트): 횡단 관심사를 모듈화한 단위. @Aspect 어노테이션으로 정의합니다.
  • Join Point (조인 포인트): Advice가 적용될 수 있는 지점. 메서드 호출, 필드 접근 등이 있습니다.
  • Pointcut (포인트컷): Join Point 중에서 실제로 Advice를 적용할 지점을 정의하는 표현식입니다.
  • Advice (어드바이스): Join Point에서 실행되는 실제 코드. @Before, @After, @Around 등으로 정의합니다.

 

주요 용도

 

  • 트랜잭션 관리: @Transactional
  • 로깅: 메서드 실행 전후 로그 기록
  • 성능 측정: 특정 메서드의 실행 시간 측정
  • 예외 처리: 공통 예외 처리 로직

 

사용법

 

먼저 spring-boot-starter-aop 의존성을 추가합니다.

XML

<dependency>
    <groupId>org.springframework.boot</groupId>
    <artifactId>spring-boot-starter-aop</artifactId>
</dependency>

@Aspect 어노테이션을 사용하여 Aspect를 정의합니다.

Java

import org.aspectj.lang.ProceedingJoinPoint;
import org.aspectj.lang.annotation.*;
import org.springframework.stereotype.Component;

@Aspect
@Component
public class LoggingAspect {

    // com.example.service 패키지 내 모든 public 메서드를 포인트컷으로 지정
    @Pointcut("execution(public * com.example.service.*.*(..))")
    private void serviceMethods() {}

    // Before Advice: 메서드 실행 전
    @Before("serviceMethods()")
    public void beforeMethod() {
        System.out.println("AOP: 메서드 실행 전");
    }

    // After Advice: 메서드 실행 후
    @After("serviceMethods()")
    public void afterMethod() {
        System.out.println("AOP: 메서드 실행 후");
    }

    // Around Advice: 메서드 실행 전후에 모두 관여
    @Around("serviceMethods()")
    public Object aroundMethod(ProceedingJoinPoint joinPoint) throws Throwable {
        System.out.println("AOP: Around - 메서드 실행 시작");
        
        Object result = joinPoint.proceed(); // 실제 메서드 실행
        
        System.out.println("AOP: Around - 메서드 실행 종료");
        return result;
    }
}

 

🎯 Filter vs Interceptor vs AOP, 언제 무엇을 써야 할까?

https://goodteacher.tistory.com/412

구분 Filter (필터) Interceptor (인터셉터) AOP (관점 지향 프로그래밍)
적용 계층 Servlet 영역 Spring MVC (Dispatcher Servlet) Spring Bean (Proxy)
제공 기능 요청/응답 변조, 인코딩, 보안 로그인/권한 체크, API 호출 로깅 트랜잭션, 로깅, 예외 처리
사용 시점 모든 웹 요청에 대한 전역적 처리 특정 컨트롤러 전후의 세밀한 처리 핵심 비즈니스 로직과 분리된 공통 기능
주요 활용 CORS, XSS 방어, 로깅, 인코딩 권한 관리, 성능 측정 트랜잭션 관리, 메서드 단위 로깅
  • 필터모든 웹 요청에 대해 공통적으로 적용해야 할 전역적인 기능(예: 보안, 인코딩)에 적합합니다.
  • 인터셉터Spring MVC에 특화되어 있으며, 특정 URL 패턴에 따라 컨트롤러 실행 전후에 로직을 적용할 때 유용합니다.
  • AOP는 핵심 비즈니스 로직과 분리된 횡단 관심사를 메서드 단위로 적용할 때 사용합니다. @Transactional과 같은 선언적 트랜잭션 처리가 대표적인 예시입니다.