Home [Java] Filter, Interceptor, AOP 비교
Post
Cancel

[Java] Filter, Interceptor, AOP 비교

자바 웹 개발을 할 때 공통 처리를 위해 Filter, Interceptor, AOP를 활용할 수 있다.

Filter, Interceptor, AOP 흐름

fia

실행 순서

Filter → Interceptor → AOP → Interceptor → Filter

비교

  • Filter, Interceptor는 Servlet 단위에서 실행되고, AOP는 메소드 앞에서 Proxy 형태로 실행된다.
  • Filter는 스프링 컨텍스트 외부에 존재하고 Interceptor, AOP는 스프링 컨텍스트 내부에 존재한다.

개념

Filter

  • Servlet 3.x 부터 추가된 기술이다.
  • Client와 Servlet 사이에서 전달되는 request와 response를 중간에서 가로채서 특정한 작업을 실행한다.
    • 클라이언트 → 필터 → 서블릿
    • 클라이언트 ← 필터 ← 서블릿
  • 스프링 범위 밖에서 처리되고, 스프링 컨테이너가 아닌 톰캣과 같은 웹 컨테이너에 의해 관리가 된다. (스프링 빈으로 등록은 가능하다.)
  • ServletRequest, ServletResponse를 제공하고, HttpServletRequest, HttpServletResponse로 다운캐스팅하여 사용할 수 있다.
    • Request와 Response를 조작할 수 있다.

구현

  • javax.servlet.Filter 인터페이스를 구현한다.
  • 메소드
    • init(FilterConfig config) 서블릿 컨테이너가 필터 인스턴스를 초기화하기 위해 호출한다.
    • doFilter(ServletRequest res, ServletResponse res, FilterChain chain) 필터에서 구현해야 하는 로직을 작성한다.
    • destroy() 필터 인스턴스를 종료시키기 전에 호출한다.
1
2
3
4
5
6
7
8
9
10
11
12
13
@WebFilter(filterName = "myFilter", urlPatterns = {"/*", "/post/*"})
public class MyFilter implements Filter {
    @Override
    public void doFilter(ServletRequest res, ServletResponse res, FilterChain chain) {
        
        // 클라이언트에서 서블릿으로 request를 넘기기 전에 실행되는 부분
        
        chain.doFilter(request, response);
        
        // 서블릿에서 클라이언트로 response를 넘기기 전에 실행되는 부분
        
    }
}

설정

필터가 어떤 URL 전 후로 실행될지 설정해주어야 한다.

  • 방법1. 필터 클래스에서 @WebFilter 애노테이션을 사용한다.

    1
    2
    
    @WebFilter(filterNamer = "myFilter", urlPatterns = {"/*", "/post/*"})
    public class MyFilter implements Filter {
    
  • 방법2. web.xml 파일에 관련 정보를 추가한다.

    • <filter>, <filter-mapping> 태그를 사용한다.
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    
      <filter>
        <filter-name>FilterName</filter-name>
        <filter-class>com.config.auth.MyFilter</filter-class>
        <init-param>
          <param-name>paramName</param-name>
          <param-value>value</param-value>
        </init-pram>
      </filter>
        
      <filter-mapping>
        <filter-name>FilterName</filter-name>
        <url-pattern>/*</url.patter>
      </filter-mapping>
      
      <filter-mapping>
        <filter-name>FilterName</filter-name>
        <url-pattern>/post/*</url.patter>
      </filter-mapping>
    

Interceptor

  • 스프링에서 DispatcherServlet과 Controller 사이에서 전달되는 HttpRequest와 HttpResponse를 중간에서 가로채서 특정한 작업을 실행한다.
  • 스프링 컨텍스트 안에서 동작한다.

구현

fia

  • 메서드
    • preHandle(HttpServletRequest request, HttpServletResponse response, Object obj) Controller가 호출되기 전에 실행된다. false를 리턴할 경우 Controller를 호출하지 않는다.
    • postHandle(HttpServletRequest request, HttpServletResponse response, Object obj, ModelAndView view) Controller가 실행된 후에 호출된다.
    • afterCompletion(HttpServletRequest request, HttpServletResponse response, Object obj, Exception e) View에서 최종 결과가 생성하는 일을 포함한 모든 일이 완료되었을 때 실행된다.
  • 방법1. HandlerInterceptor 인터페이스를 구현한다.
    • 모든 메서드를 구현해야 한다.
  • 방법2. HandlerInterceptorAdapter 클래스를 상속받는다.
    • 메서드가 이미 구현되어 있으므로, 필요한 메서드만 오버라이드한다.

설정

인터셉터가 어떤 URL 전 후로 실행될지 설정해주어야 한다.

  • 방법1. spring-servlet.xml 설정 파일을 생성한다.

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    
    <mvc:interceptor>
        	<!-- 인터셉터가 실행되어야 하는 URL -->
        	<mvc:mapping path="/" /> 
            <mvc:mapping path="/post/*" /> 
          
        	<!-- 인터셉터가 실행되지 않아야하는 URL -->
        	<mvc:exclude-mapping path="/logout"/>
          
            <bean class="com.config.auth.AuthInterceptor" />
    </mvc:interceptor>
    
  • 방법2. WebMvcConfigurer 인터페이스를 구현한다.

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    
    @Configuration
    public class WebMvcConfig implements WebMvcConfigurer {
      
        private final AuthInterceptor authInterceptor;
      
        public WebMvcConfig(AuthInterceptor authInterceptor) {
            this.authInterceptor = authInterceptor;
        }
      
        public void addInterceptors(InterceptorRegistry registry) {
            registry.addInterceptor(authInterceptor).addPathPatterns("/", "/post/**");
        }
      
    }
    

AOP

  • AOP(Aspect Oriented Programming)의 약자, 관점 지향 프로그래밍
    • 소스 코드에서 반복해서 쓰는 코드들, 즉 공통된 로직을 모듈화한다. 이 공통된 로직을 관점(Aspect)라고 한다.
  • 메소드 전후 지점 중에 원하는 지점을 설정해서 특정한 작업을 실행한다.

구현

  • @Aspect를 붙여서 해당 클래스가 Aspect라는 것을 나타낸다.
  • @Component를 붙여서 스프링 빈으로 등록한다.
  • 포인트 컷을 지정한다.
    • @Before : 대상 메서드의 수행 전
    • @After : 대상 메서드의 수행 후
    • @After-returning : 대상 메서드의 정상적인 수행 후
    • @After-throwing : 예외 발생 후
    • @Around : 대상 메서드의 수행 전/후

정리

Filter

  • 서블릿 동작 전 후 과정에 부가적인 로직을 처리
  • 웹 컨테이너에서 관리한다. 그래서 스프링과 무관하게 전역적으로 처리해야 하는 작업들을 처리
    • 인코딩 변환, 보안 검사(XSS 방어 등)
    • 예외 발생 시 Web Application에서 예외 처리
    • 스프링 컨테이너까지 요청이 전달되지 못하고 차단되므로 안정성을 더욱 높일 수 있다.
  • ServletRequest, ServletResonse 객체를 조작할 수 있다.
    • 웹 애플리케이션에 전반적으로 사용되는 기능을 구현하기 적합
  • web.xml 에서 적용한다.

Interceptor

  • 컨트롤러 동작 전 후 과정에 부가적인 로직을 처리
  • 스프링 컨테이너에서 관리한다. 클라이언트 요청과 관련해서 전역적으로 처리해야하는 작업들을 처리할 수 있다.
    • 인증 및 인가(로그인 체크, 권한 체크 등)
  • HttpServletReqeust, HttpServletResponse 등과 같은 객체를 제공받는다. (Request, Response 조작은 불가능)
    • 컨트롤러로 넘겨주기 위한 정보를 가공하는 기능을 구현하기 적합
  • servlet-context.xml 에서 적용한다.

AOP

  • 메서드 동작 전 후 과정에 부가적인 로직을 처리한다.
  • Interceptor와 Filter는 주소(URL)로 대상을 구분해서 처리하지만, AOP는 주소, parameter, annotation 등 PointCut이 지원하는 다양한 방법으로 대상을 지정할 수 있다.
  • 비즈니스 단에서 세밀하게 조정하는 기능을 구현하기 적합
    • 로깅, 트랜잭션, 에러 처리 등

출처

This post is licensed under CC BY 4.0 by the author.