Filter, Interceptor, AOP 의 차이점

이가희·2025년 3월 29일

spring + java

목록 보기
8/14
post-thumbnail

이번에는 Spring 🍃 하면 알아야 할 기본 개념 중 하나인
Filter, Interceptor, AOP 들의 개념과 차이점들에 대해 살펴보겠다.


개발을 하다보면 로그인 관련 처리, 권한 체크, 로그와 같이 공통 기능 이 생긴다.

Filter, Interceptor, AOP 가 이 공통 기능 수행에 대한 다양한 기능을 제공하는데 각각의 특성을 살펴보며, 어떤 공통 기능엔 어떤 것을 사용하면 좋을지 알아보자.

1. Filter, Interceptor, AOP 의 개념과 흐름

*이미지 출처 : https://sallykim5087.tistory.com/158

Interceptor 와 Filter 는 Servlet 단위에서 실행되고, AOP 는 method 앞에 Proxy 패턴의 형태로 실행된다.
전체적인 흐름은 위의 이미지를 참조하면서, 하나씩 개념을 살펴보겠다.


1.1 Filter

필터는 스프링 컨텍스트 외부에 존재하여 Java Servlet 에서 제공하는 기능이다.

Servlet 에 대해 알고싶다면 이곳으로!

DispatcherServlet 이전에 실행되어 요청과 응답에 대한 전처리/후처리를 수행한다.

또한 FilterChain 을 통해 여러 필터가 연쇄적으로 동작하게 할 수도 있다.
Filter는 보통 로깅, 인코딩 설정, CORS 처리 등에 사용되는데,
요청이 DispatcherServlet 에 전달되기 전에 헤더 검사하기와 같은 일들을 Filter를 통해 처리하면 좋을 것이다.

Filter 는 servlet 의 Filter 인터페이스를 구현해서 만들 수 있고, 이 인터페이스에는 3가지 메소드가 있다.

  1. init() : 필터가 생성될 때 수행되는 메소드
  2. doFilter() : Request , Response 가 필터를 거칠 때 수행되는 메소드
  3. destroy() : 필터가 소멸될 때 수행되는 메소드
@Slf4j
public class MyFilter implements Filter {
    @Override
    public void init(FilterConfig filterConfig) throws ServletException {
        log.info("Filter 생성!");
    }

    @Override
    public void doFilter(ServletRequest servletRequest, ServletResponse servletResponse, FilterChain filterChain) throws IOException, ServletException {
        log.info("필터 시작!=");
        filterChain.doFilter(servletRequest, servletResponse);
        log.info("필터 종료!");
    }

    @Override
    public void destroy() {
        log.info("Filter 소멸!");
    }
}

만든 클래스를 FilterRegistrationBean을 이용해 등록하면 된다.

@Configuration
public class Config{

    @Bean
    public FilterRegistrationBean firstFilterRegister() {
        FilterRegistrationBean registrationBean = new FilterRegistrationBean(new MyFilter());
        return registrationBean;
    }
}

1.2 Interceptor

인터셉터는 Spring MVC 내에서 요청이 컨트롤러에 도달하기 전이나 뷰가 렌더링되기 전/후에 가로채서 작업을 할 수 있게 해 준다.

보통 HandlerInterceptorAsyncHandlerInterceptor 을 구현해서 사용한다.

핵심 메서드는 3가지가 있다.

public interface HandlerInterceptor {

    default boolean preHandle(HttpServletRequest request,
                              HttpServletResponse response,
                              Object handler) throws Exception {
        return true; // false 반환 시 컨트롤러로 진행되지 않음
    }

    default void postHandle(HttpServletRequest request,
                            HttpServletResponse response,
                            Object handler,
                            ModelAndView modelAndView) throws Exception {}

    default void afterCompletion(HttpServletRequest request,
                                 HttpServletResponse response,
                                 Object handler,
                                 Exception ex) throws Exception {}
}
  • preHandle : 컨트롤러 진입 전에 실행되며, 인증/권한 검사, 로깅 등에 쓰인다.
  • postHandle : 컨트롤러 실행 후, View 렌더링 전에 실행되며, 로그 수집, 모델 조작 등에 쓰인다.
  • afterComplection : View 렌더링 후에 실행되며, 리소스 정리 , 예외 처리 로깅 등에 쓰인다.

구현한 인터페이스는 WebMvcConfigurer를 구현한 클래스에 등록하면 된다.


@Configuration
public class WebConfig implements WebMvcConfigurer {
    @Override
    public void addInterceptors(InterceptorRegistry registry) {
        registry.addInterceptor(new MyInterceptor())
                .addPathPatterns("/api/**")    // 적용 경로
                .excludePathPatterns("/login"); // 제외 경로
    }
}

1.3 Spring AOP

Spring AOP 는 관심사의 분리 를 실현한 방법인데,
여기서 관심사의 분리란 핵심 로직과 공통 로직 (로깅, 트랜잭션, 보안 등) 을 분리하여 코드 중복 없이 유지보수가 쉬운 구조를 만드는 것이다.

더 정확히 말하자면, 관점 지향 프로그래밍 (AOP) 은 어떤 로직을 헥심적인 관점, 부가적인 관점으로 나누어서 보고 그 관점을 기준으로 각각 모듈화하는 것이다.

Spring AOP 는 프록시 기반 AOP로 메서드 단위의 런타임 AOP 를 제공하고,Spring Bean 에만 적용이 가능하다.

🔍 AOP 의 주요 개념

Aspect : 흩어진 관심사를 모듈화 한 것. 주로 부가기능을 모듈화함.
Target : Aspect를 적용하는 곳 (클래스, 메서드 .. )
Advice : 실질적으로 어떤 일을 해야할 지에 대한 것, 실질적인 부가기능을 담은 구현체
JointPoint : Advice가 적용될 위치, 끼어들 수 있는 지점. 메서드 진입 지점, 생성자 호출 시점, 필드에서 값을 꺼내올 때 등 다양한 시점에 적용가능
PointCut : JointPoint의 상세한 스펙을 정의한 것. 'A란 메서드의 진입 시점에 호출할 것'과 같이 더욱 구체적으로 Advice가 실행될 지점을 정할 수 있음

+) 실질적인 구현체인 Advice 의 종류는 아래와 같다.

Advice 종류어노테이션설명
전처리@Before메서드 실행 전
후처리 (정상 시)@AfterReturning메서드가 예외 없이 완료된 후
후처리 (예외 시)@AfterThrowing예외가 발생한 후
항상 후처리@After예외 상관없이 항상
둘 다 감싸기@Around메서드 실행 전/후 모두 제어 가능

🔍 Spring AOP 사용 방법

로깅할 때의 아주 간단한 사용 예시를 보자.


@Aspect
@Component
public class LoggingAspect {

    @Before("execution(* com.example.service.UserService.getUser(..))")
    public void logBeforeUserGet() {
        System.out.println("메소드 실행 전...");
    }
}

  • @Aspect : 이 어노테이션을 붙이면 해당 클래스에 스프링 AOP 를 적용할 수 있게 된다.
  • @Component : 이 어노테이션을 통해 Spring Bean 으로 등록한다. 등록을 해야 AOP 가 실질적으로 작동한다.
  • @Before : Advice 의 종류 중 하나로 메서드 실행 전에 작동된다.
  • execution : 포인트컷 표현식 중 하나이다. execution을 사용하면 메소드 실행 시점을 기준으로 동작시킬 수 있다. 이밖에도 within , this , target 등이 있다.
포인트컷설명
execution메소드 실행 시점을 기준으로 동작 (가장 일반적)
within특정 클래스나 패키지 안의 모든 메소드를 타겟팅
this프록시 객체(스프링 AOP에서 생성된 프록시)의 타입 기준
target실제 대상 객체의 타입 기준
args전달되는 매개변수의 타입 기준
@target대상 객체에 어노테이션이 붙었는지 기준
@within클래스 수준에서 어노테이션이 붙었는지 기준
@annotation특정 어노테이션이 붙은 메소드를 타겟팅
bean특정 이름의 빈을 타겟으로 설정할 때 사용

포인트컷 표현식은
리턴타입 패키지 클래스 메소드 매개변수 순서로 지정할 수 있다.
만든 표현식들은 && , || , ! 을 사용해서 결합할 수도 있다.

리턴타입의 경우 * 는 모든 리턴타입 허용이고, void, String 등이 있다.

.. 은 여러 개 혹은 생략 가능하다는 의미인데 파라미터에 ..이 있으면, 매개변수와 상관 없이 모든 해당 메소드에 적용한다는 뜻이 되고,
패키지에 ..이 있으면 해당 경로의 모든 하위 패키지를 포함한다는 의미이다.

그래서 위의 코드에서
* com.example.service.UserService.getUser(..)com.example.service 경로의 Userservice 클래스의 getUser 라는 메소드가 실행될 때 적용된다는 말이다.
이때, 모든 리턴 타입을 허용하고, 모든 매개변수 (없는 것도) 허용한다.

2. 정리

정리하자면

Filter 는 스프링 컨텍스트 외부에 존재하여 스프링의 앞단인 DispatcherServlet이 실행되기 전에 실행이 되고,

Interceptor 은 Spring MVC 내에서 요청이 컨트롤러에 도덜하기 전, 뷰가 렌더링 되기 전 후에 작업이 실행되며,

Spring AOP 는 메소드 단위로 실행 시점을 미세하게 조정할 수 있다.


Spring 주요 개념들에 대해 빠르게 간단하게 살펴보았다.
심화적으로 깊게 공부할 수 있는 개념이니, 시간이 될 때 더욱 심층적으로 보아도 좋을 것 같다.

참조
Spring Framework - Filters
Spring Framework - AOP
Spring Framework - Interceptor
https://sallykim5087.tistory.com/158
https://gardeny.tistory.com/35
https://engkimbs.tistory.com/entry/스프링AOP
정저우의 스프링 부트 핵심 가이드
https://hstory0208.tistory.com/entry/Spring-%EC%8A%A4%ED%94%84%EB%A7%81-AOP-Aspect-%EC%82%AC%EC%9A%A9%EB%B2%95

profile
안녕하세요 개발하는 사람입니다.

0개의 댓글