스프링 Filter,Interceptor, AOP

dragonappear·2022년 1월 27일
0

Spring & SpringBoot

목록 보기
4/11


출처


공통 프로세스

웹개발을 하다보면 공통적으로 처리해야 할 부분들이 많다. 로그인 관련 처리, 권한 체크, pc와 모바일웹의 분기처리 등등 이 있다.

공통업무에 관련된 코드를 중복해서 작성한다면 소스관리도 안될뿐더러 유지보수도 힘들어진다.

그러므로 공통 부분은 빼서 관리하는 것이 좋다.

이러한 공통업무를 프로그램의 앞,중간,뒤에 추가하여 자동으로 처리할 수 있는 방법이 있다.

위와 같은 공통처리를 위해 활용할 수 있는 것이 3가지가 있다.
1. Filter
2. Interceptor
3. AOP

스프링에서 사용되는 Filter,Interceptor,AOP 세 가지 기능은 모두 무슨 행동을 하기전에 먼저 실행하거나, 실행한 후에 추가적인 행동을 할 떄 사용되는 기능들이다.

Filter, Interceptor, AOP의 흐름


출처:https://goddaehee.tistory.com/154

  • 인터셉터와 필터는 서블릿단위에서 실행된다. 반면 AOP는 메서드 앞에 Proxy 패턴의 형태로 실행된다.
  • 실행 순서를 보면 Filter가 가장 밖에 있고 그 안에 Interceptor, 그 안에 AOP가 있는 형태이다.
  • 따라서 요청이 들어오면 Filter->Interceptor->AOP->Interceptor->Filter 순으로 거치게 된다.
  1. 서버를 실행시켜 서블릿이 올라오는 동안에 init이 실행되고, 그 후 doFilter가 실행된다.
  2. 컨트롤러에 들어가기 전 preHandler가 실행된다
  3. 컨트롤러에서 나와 postHandler, after Completion, doFilter 순으로 진행이 된다.
  4. 서블릿 종료 시 destroy가 실행된다.

Filter

말 그대로 요청과 응답을 거른뒤 정제하는 역할을 한다.

서블릿 필터는 DispatcherServlet 이전에 실행이 되는데 필터가 동작하도록 지정된 자원의 앞단에서 요청내용을 변경하거나, 여러가지 체크를 수행할 수 있다.

또한 자원의 처리가 끝난 후 응다밴용에 대해서도 변경하는 처리를 할 수 있다. 보통 web.xml에 등록하고, 일반적으로 인코딩 변환 처리, XSS방어 등의 요청에 대한 처리로 사용된

EX)

<!-- 한글 처리를 위한 인코딩 필터 -->

<filter>

    <filter-name>encoding</filter-name>

    <filter-class>org.springframework.web.filter.CharacterEncodingFilter</filter-class>

    <init-param>

        <param-name>encoding</param-name>

        <param-value>UTF-8</param-value>

    </init-param>

</filter>

<filter-mapping>

    <filter-name>encoding</filter-name>

    <url-pattern>/*</url-pattern>

</filter-mapping>

해당 필터의 이름은 encoding, 값은 UTF-8인 파라미터를 정의하고 있다.
필터의 URL-PATTERN을 /*로 정의하면 servlet, jsp뿐만 아니라 이미지와 같은 모든 자원의 요청에도 호출 된다.

필터의 실행메서드

  • init() - 필터 인스턴스 초기화
  • doFilter() - 전/후처리
  • destory() - 필터 인스턴스 종료

Interceptor

  • 요청에 대한 작업 전/후로 가로챈다고 보면 된다.

  • 필터는 스프링 컨텍스트 외부에 존재하여 스프링과 무관한 자원에 대해 동작한다.

  • 하지만 인터셉터는 스프링의 DispatcherServlet이 컨트롤러를 호출하기 전,후로 끼어들기 때문에 스프링 컨텍스트(Context,영역) 내부에서 Controller(Handler)에 관한 요청과 응답에 대해 처리한다.

  • 스프링의 모든 빈 객체에 접근할 수있다.

  • 인터셉터는 여러 개를 사용할 수 있고, 로그인체크,권한체크,프로그램 실행시간 계산작업 로그확인 등의 업무처리를 할 수 있다.

인터셉터의 실행메서드

  • preHandler() - 컨트롤러 메서드가 실행되기 전
  • postHanler() - 컨트롤러 메서드 실행직후 view페이지 렌더링 되기 전
  • afterCompletion() - view페이지가 렌더링 되고 난 후

AOP

OOP를 보완하기 위해 나온 개념

  • 객체 지향의 프로그래밍을 했을때 중복을 줄일 수 없는 부분을 줄이기 위해 종단면(관점)에서 바라보고 처리한다.
  • 주로 로깅,트랜젝션,에러처리 등 비지니스 단의 메서드에서 조금 더 세밀하게 조정하고 싶을 때 사용한다.
  • Interceptor나 Filter와는 달리 메소드 전후의 지점에 자유롭게 설정이 가능하다.
  • Interceptor와 Filter는 주소로 대상을 구분해서 걸러내야하는 반면, AOP는 주소, 파라미터, 애노테이션 등 다양한 방법으로 대상을 지정할 수 있다.
  • AOP의 Advice와 HandlerInterceptor의 가장 큰 차이는 파라미터의 차이다.
    • Advice의 경우 JoinPoint나 ProceedingJoinPoint 등을 활용해서 호출한다.
    • 반면 HandlerInterceptor는 Filter와 유사하게 HttpServletRequest, HttpServletResponse를 파라미터로 사용한다.

AOP 포인트컷

  • @Before: 대상 메서드의 수행 전
  • @After: 대상 메서드의 수행 후
  • @After-returning: 대상 메서드의 정상적인 수행 후
  • @After-throwing: 예외발생 후
  • @Around: 대상 메서드의 수행 전/후

세가지의 사용에 대한 결론

Filter

  • 전체적인 Request단에서 어떤 처리가 필요할때
  • 인증,이미지변환,데이터압축,암호화필터,토크나이징 필터,XML 컨텐츠를 변형하는 XSLT 필터,URL 및 기타정보를 캐시하는 필터
  • 문자 인코딩등

Interceptor

  • 세션 및 쿠키 체크하는 http 프로토콜 단위로 처리해야 하는 업무가 있을 때
  • 로그인 세션 체크 등

AOP

  • 비즈니스 단에서 세밀하게 조정하고 싶을때
  • 로깅,트랜잭션,에러처리 등

Filter 와 OncePerRequestFilter

  • Filter를 조금 더 확장하여 스프링에서 제공하는 필터가 있는데 그것이 바로 GenericFilterBean이다.
    • GenericFilterBean은 기존 Filter에서 얻어올 수 없는 정보였던 Spring의 설정 정보를 가져올 수 있게 확장된 추상 클래스이다.
      • 내부를 까보면 이것 저것 얻어올 수 있는 정보가 꽤 있다는 사실을 알 수 있다. (setter 메서드가 있어서 정보 저장도 가능)
  • 이 두 필터(GenericFilterBean,Filter)는 한 가지 공통점이 있다. 매 서블릿마다 호출이 된다는 것이다.
    • 서블릿은 사용자의 요청을 받으면 서블릿을 생성해 메모리에 저장해두고, 같은 클라이언트의 요청을 받으면 생성해둔 서블릿 객체를 재활용하여 요청을 처리한다.
  • 여기까지는 서블릿의 기본적인 내용이다. 문제는 이 서블릿이 다른 서블릿으로 dispatch되는 경우가 있을 수 있다.
    • 가장 대표적으로 Spring Security에서 인증과 접근 제어 기능이 Filter로 구현되어진다.
    • 이러한 인증과 접근 제어는 RequestDispatcher 클래스에 의해 다른 서블릿으로 dispatch되게 되는데, 이 때 이동할 서블릿에 도착하기 전에 다시 한번 filter chain을 거치게 된다.
    • 바로 이 때 또 다른 서블릿이 우리가 정의해둔 필터가 FilterGenericFilterBean로 구현된 filter를 또 타면서 필터가 두 번 실행되는 현상이 발생할 수 있다.
    • 이런 문제를 해결하기 위해 등장한 것이 바로 OncePerRequestFilter이다.
      • OncePerRequestFilter는 그 이름에서도 알 수 있듯이 모든 서블릿에 일관된 요청을 처리하기 위해 만들어진 필터이다.
      • 이 추상 클래스를 구현한 필터는 사용자의 한번 요청 당 딱 한번만 실행되는 필터를 만들 수 있다.

  • 서블릿을 실행하는 동안 다른 서블릿에 대한 다른 요청이 있을 수 있으며, 다른 서블릿에도 동일한 Filter가 있다. 이러한 경우 Filter는 다시 한번 더 실행된다.
  • OncePerRequestFilter는 이 동작을 방지한다. 한 번의 request에 대해, OncePerRequestFilter는 정확하게 한 번만 실행된다. 이러한 동작은 보안 인증에 도움이 된다.

0개의 댓글