Spring Filter, Interceptor, AOP
1. Filter, Interceptor, AOP의 흐름
실행 순서:Filter → Interceptor → AOP → Interceptor → Filter
2. 개념
1) Filter
- Dispatcher Servlet 전/후 ServletRequest/ServletResponse 객체 변경 및 조작 수행 가능
- WAS 내의 ApplicationContext에서 등록된 필터가 실행
- WAS 구동 시 FilterMap이라는 배열에 등록되고, 실행 시 Filter chain을 구성하여 순차적으로 실행
- Spring Context 외부에 존재하여 Spring과 무관한 자원에 대해 동작
- 일반적으로 web.xml에 설정
- 예외 발생 시 Web Application에서 예외 처리
- ex. 인코딩 변환, XSS 방어 등
[ 필터(Filter)의 메서드 ]
필터를 추가하기 위해서는 javax.servlet의 Filter 인터페이스를 구현(implements) 해야 하며 이는 다음의 3가지 메서드를 가지고 있다.
- init(): 필터 인스턴스 초기화.
- 필터 객체를 초기화하고 서비스에 추가하기 위한 메서드이다. 웹 컨테이너가 1회 init 메소드를 호출하여 필터 객체를 초기화하면 이후의 요청들은 doFilter를 통해 처리된다.
- doFilter(): 실제 전/후 로직 처리
- url-pattern에 맞는 모든 HTTP 요청이 디스패처 서블릿으로 전달되기 전에 웹 컨테이너에 의해 실행되는 메소드이다. doFilter의 파라미터로는 FilterChain이 있는데, FilterChain의 doFilter 통해 다음 대상으로 요청을 전달하게 된다. chain.doFilter() 전/후에 우리가 필요한 처리 과정을 넣어줌으로써 원하는 처리를 진행할 수 있다.
- destroy(): 필터 인스턴스 종료
- 필터 객체를 서비스에서 제거하고 사용하는 자원을 반환하기 위한 메소드이다. 이는 웹 컨테이너에 의해 1번 호출되며 이후에는 이제 doFilter에 의해 처리되지 않는다.
2) Interceptor
- Dispatcher Servlet 이후 Controller 호출 전/후에 끼어들어 기능 수행
- Spring Context 내부에서 Controller의 요청과 응답에 관여하며 모든 Bean에 접근 가능
- 일반적으로 servlet-context.xml에 설정
- 예외 발생 시 @ControllerAdvice에서 @ExceptionHandler를 사용해 예외 처리
- ex. 로그인 체크, 권한 체크, 로그 확인 등
스프링의 모든 빈 객체에 접근할 수 있다. 인터셉터는 여러 개를 사용할 수 있고 로그인 체크, 권한 체크, 프로그램 실행 시간 계산 작업 로그 확인 등의 업무처리에 사용한다.
- preHandler(): 컨트롤러 메서드가 실행되기 전
- 컨트롤러가 호출되기 전에 실행된다. 그렇기 때문에 컨트롤러 이전에 처리해야 하는 전처리 작업이나 요청 정보를 가공하거나 추가하는 경우에 사용할 수 있다. preHandle의 3번째 파라미터인 handler 파라미터는 핸들러 매핑이 찾아준 컨트롤러 빈에 매핑되는 HandlerMethod라는 새로운 타입의 객체로써, @RequestMapping이 붙은 메서드의 정보를 추상화한 객체이다. 또한 preHandle의 반환 타입은 boolean인데 반환값이 true이면 다음 단계로 진행이 되지만, false라면 작업을 중단하여 이후의 작업(다음 인터셉터 또는 컨트롤러)은 진행되지 않는다.
- postHanler(): 컨트롤러 메소드 실행 직후 view 페이지 렌더링 되기 전
- 컨트롤러를 호출된 후에 실행된다. 그렇기 때문에 컨트롤러 이후에 처리해야 하는 후처리 작업이 있을 때 사용할 수 있다. 이 메서드에는 컨트롤러가 반환하는 ModelAndView 타입의 정보가 제공되는데, 최근에는 Json 형태로 데이터를 제공하는 RestAPI 기반의 컨트롤러(@RestController)를 만들면서 자주 사용되지는 않는다.
- afterCompletion(): view 페이지가 렌더링 되고 난 후
- 모든 뷰에서 최종 결과를 생성하는 일을 포함해 모든 작업이 완료된 후에 실행된다. 요청 처리 중에 사용한 리소스를 반환할 때 사용하기에 적합하다.
# Filter와 Interceptor의 비교
- Filter는 WAS단에 설정되어 Spring과 무관한 자원에 대해 동작하고, Interceptor는 Spring Context 내부에 설정되어 컨트롤러 접근 전, 후에 가로채서 기능 동작
- Filter는 doFilter() 메소드만 있지만, Interceptor는 pre와 post로 명확하게 분리
- Interceptor의 경우 AOP 흉내 가능
- handlerMethod(@RequestMapping을 사용해 매핑 된 @Controller의 메소드)를 파라미터로 제공하여 메소드 시그니처 등 추가 정보를 파악해 로직 실행 여부 판단 가능
- 필터와 인터셉터는 각각 관리되는 컨테이너와 Request/Response의 조작 가능 여부가 다르고, 그에 따라 용도가 다르다.
- 필터는 Request와 Response를 조작할 수 있지만 인터셉터는 조작할 수 없다.
- 필터에서는 기본적으로 스프링과 무관하게 전역적으로 처리해야 하는 작업들을 처리할 수 있다. 대표적인 예시로 보안과 관련된 공통 작업이 있다. 필터는 인터셉터보다 앞단에서 동작하기 때문에 전역적으로 해야 하는 보안 검사(XSS 방어 등)를 하여 올바른 요청이 아닐 경우 차단을 할 수 있다. 그러면 스프링 컨테이너까지 요청이 전달되지 못하고 차단되므로 안정성을 더욱 높일 수 있다. 또한 필터는 이미지나 데이터의 압축이나 문자열 인코딩과 같이 웹 애플리케이션에 전반적으로 사용되는 기능을 구현하기에 적당하다. Filter는 다음 체인으로 넘기는 ServletRequest/ServletResponse 객체를 조작할 수 있다는 점에서 Interceptor보다 훨씬 강력한 기술이다.
- 인터셉터에서는 클라이언트의 요청과 관련되어 전역적으로 처리해야 하는 작업들을 처리할 수 있다. 대표적으로 세부적으로 적용해야 하는 인증이나 인가와 같이 클라이언트 요청과 관련된 작업 등이 있다. 예를 들어 특정 그룹의 사용자는 어떤 기능을 사용하지 못하는 경우가 있는데, 이러한 작업들은 컨트롤러로 넘어가기 전에 검사해야 하므로 인터셉터가 처리하기에 적합하다. 또한 인터셉터는 필터와 다르게 HttpServletRequest나 HttpServletResponse 등과 같은 객체를 제공받으므로 객체 자체를 조작할 수는 없다. 대신 해당 객체가 내부적으로 갖는 값은 조작할 수 있으므로 컨트롤러로 넘겨주기 위한 정보를 가공하기에 용이하다. 예를 들어 JWT 토큰 정보를 파싱 해서 컨트롤러에게 사용자의 정보를 제공하도록 가공할 수 있는 것이다. 그 외에도 우리는 다양한 목적으로 API 호출에 대한 정보들을 기록해야 할 수 있다. 이러한 경우에 HttpServletRequest나 HttpServletResponse를 제공해주는 인터셉터는 클라이언트의 IP나 요청 정보들을 포함해 기록하기에 용이하다.
3) AOP
AOP는 OOP를 보완하기 위해 나온 개념이다. 객체 지향의 프로그래밍을 했을 때 중복을 줄일 수 없는 부분을 줄이기 위해 종단면(관점)에서 바라보고 처리한다.
주로 ‘로깅’, ‘트랜잭션’, ‘에러 처리’ 등 비즈니스단의 메서드에서 조금 더 세밀하게 조정할 때 사용한다.
Interceptor나 Filter와는 달리 메소드 전후의 지점에 자유롭게 설정이 가능하다. Interceptor와 Filter는 주소로 대상을 구분해서 걸러내야 하는 반면, AOP는 주소, 파라미터, 애노테이션 등 다양한 방법으로 대상을 지정할 수 있다.
AOP의 Advice와 HandlerInterceptor의 가장 큰 차이는 파라미터의 차이다. Advice의 경우 JoinPoint나 ProceedingJoinPoint 등을 활용해서 호출한다. 반면 HandlerInterceptor는 Filter와 유사하게 HttpServletRequest, HttpServletResponse를 파라미터로 사용한다.
- @Before: 대상 메서드의 수행 전
- @After: 대상 메소드의 수행 후
- @After-returning: 대상 메소드의 정상적인 수행 후
- @After-throwing: 예외발생 후
- @Around: 대상 메서드의 수행 전, 후
3. 차이점
1) 적용 시점이 다름
- Filter → Interceptor → AOP
2) 적용 방식이 다름
- Filter: web.xml
- Interceptor: servlet-context.xml
3) 실행 위치가 다름
- Filter: WAS 웹 컨텍스트에서 실행
- Interceptor : 스프링 컨텍스트에서 실행
- AOP: 메소드 앞에 Proxy 패턴의 형태로 실행
4. 세 가지의 사용에 대한 결론
*Filter
-전체적인 Request단에서 어떤 처리가 필요할 때
-인증, 이미지 변환, 데이터 압축, 암호화 필터, 토크 나이징 필터, XML 콘텐츠를 변형하는 XSLT 필터,
URL 및 기타 정보를 캐시 하는 필터
-문자 인코딩 등
*Interceptor
-세션 및 쿠키 체크하는 http 프로토콜 단위로 처리해야 하는 업무가 있을 때
-로그인 세션 체크 등
*AOP
-비즈니스 단에서 세밀하게 조정하고 싶을 때
-로깅, 트랜잭션, 에러 처리 등
# 출처 :
https://dejavuhyo.github.io/posts/spring-filter-interceptor-aop-differences/
https://mangkyu.tistory.com/173 [MangKyu's Diary]
'Web_Backend > Spring' 카테고리의 다른 글
3.Spring AOP (0) | 2024.07.12 |
---|---|
2.Spring DI (0) | 2024.07.12 |
1.Spring Framework와 IoC (0) | 2024.07.12 |
AOP (0) | 2022.05.03 |
[스프링 입문 - 코드로 배우는 스프링 부트, 웹 MVC, DB 접근 기술 - 인프런] 1. 프로젝트 생성 (0) | 2021.01.10 |