Filter, Intercepter, AOP

김동현·2024년 9월 8일

CS 탐험

목록 보기
1/2
post-thumbnail

서론

항상 남이 해주던 보안기능을 공부하고 적용하는 시간을 가질 것이다.
이전에는 로그인 관련 처리 기능과 관련한 세션 인증 및 토큰 인증 방식을 공부했었다. 이전의 Spring을 배울 때 인터셉터, AOP와 관련하여 배웠긴 했지만 그 당시 배우기만 하고 적용을 해보질 않아서 기억이 희미해졌다. 하지만 이러한 내용을 모른다면 Spring 백엔드 개발자라 할 수 없기에 이번 기회에 개념을 확실히 잡아보려 한다!!!

공통 기능 구현의 분리

공통 기능과 핵심 기능은 분리하여 개발하는 것이 좋다고 느낀다. 하지만 메소드만 따로 빼서 적용 하는가? 따로 빼서 적용한다 ㅇㅇ..
기능을 분리하는 방법에는 3가지가 있다.
Filter, Intercepter, AOP
3일에 걸쳐 이 세 부분에 대해 공부를 했는데 새로운 지식을 얻는 것 뿐만아닌 이전에 배운 Servlet지식을 더 확실히 이해할 수 있었다.
백엔드 개발을 하면서 공통 기능에는

  • 로그인 인증
  • 예외 처리
  • 로깅
  • 트랜잭션 관리
    등등 이렇게 존재했었다.
    프로젝트를 하면서 로깅과 예외는 직접 코드와 메소드를 작성하여 사용하였고, 트랜잭션은 어노테이션 적용만으로 사용했었다. 그래서 이러한 공통 기능을 프로젝트에서 직접 분리하여 적용해볼 계획이다. 3가지 분리 방법을 정리 후에 공통 기능에 맞는 분리 방법을 선택하여 사용할 것이다.

Filter

Filter는 Servlet단위에서 실행되며, 스프링 기능이 아닌 자바 서블릿에서 제공하는 기능이다.
Filter는 FilterChain을 통해 여러 필터가 연쇄적으로 동작하게 할 수 있다.
ServletRequest 혹은 ServletResponse를 교체할 수 있다.
Filter는 주로 XXS 방어, 인코딩 변환 처리, 요청에 대한 인증, 권한 체크등을 하는데에 쓰인다.

Filter 메소드

  1. init(): 필터가 생성될 때 수행되는 메소드
  2. doFilter(): Request, Response가 필터를 거칠 때 수행되는 메소드 → 오버라이딩 해줘야함
  3. destroy(): 필터가 소멸될 때 수행되는 메소드

Servlet Filter 등록하는 방법

  1. @Component 사용
    • 모든 URL에 적용됨
  2. @WebFilter & @ServletComponentScan 사용
    • @WebFilter(urlPatterns = “/users/me/*”) 적용하여 필터 커스텀화
    • @ServletComponentScan 애플리케이션에 적용하여 필터 활성화
      • 평소 사용하던 @Component처럼 Bean을 등록해주는 건데 대상이 WebFilter나 WebServlet, WebListen와 같이 Servlet 객체들을 Servlet 컨테이너에 올려주는 역할을 함
    • 순서 지정할 수 없음
  3. FiterRegistrationBean 사용
    • 필터를 설정해주고, Order, urlPatterns를 설정할 수 있음

FilterChain이 실행될 때 구현체 중 하나인 ApplicationFilterChain이 실행됨
Mocking하여 테스트를 돌릴 때는 MockFilterChain이 실행됨

Servlet Filter 동작 방식

필터의 배열 중에서 선택?

  • 자바 표준 스펙
  • 다음 필터를 실행하기 위해 개발자가 명시적으로 작성해줘야한다.
  • ServletRequest, ServletResponse를 필터 체이닝 중간에 새로운 객체로 바꿀 수 있다.
  • 필터에서 예외가 발생하면 @ControllerAdvice에서 처리하지 못한다.

Servlet 컨테이너는 Servlet의 생명주기를 관리하는 객체이다.


Intercepter

Intercepter란 컨트롤러에 들어오는 혹은 나가는 요청 응답 객체를 가로채 제어할 수 있는 방법이다.

Intercepter 작동원리

  1. 요청 → Filter → DispatcherServlet
  2. Dispatcher Servlet에서 HandlerMapping을 통해 Handler(Controller)를 찾음
  3. 찾았으면 HandlerMapping은 해당 컨트롤러와 연결된 Intercepter 체인을 생성한다.
  4. Intercepter객체의 preHandle함수를 호출
  5. 그 후 HandlerAdapterList에서 적절한 HandlerAdapter를 찾음
  6. 찾은 HandlerAdapter를 통해 Handler(Controller) 호출
  7. Controller 실행 이후 Intercepter객체의 postHandle함수를 호출
  8. 그 후 클라이언트에게 응답을 전송
  9. Http 요청-응답 사이클이 완료된 후 Intercepter의 AfterCompletion함수를 호출

Intercepter 메소드

  1. preHandle()
  2. postHandle()
  3. AfterCompletion()

Intercepter 적용 방법

인터셉터를 등록하려면 Spring MVC 설정에서 등록해야 합니다. WebMvcConfigurer 인터페이스의 addInterceptors 메서드를 사용하여 인터셉터를 등록할 수 있습니다.

  1. WebConfig에서 Interceptor 등록
  2. HandlerInterceptor 메소드 구현

AOP

AOP란 Aspect-Oriented Programming으로 관점 지향 프로그래밍 입니다.

관점이란 부가 기능과 그 적용처를 정의하고 합쳐서 모듈로 만든 것입니다. 이러한 관점을 기준으로 다양한 기능을 분리하여 보는 프로그래밍 입니다.

AOP 적용 방식

  1. 컴파일 시점 적용
    • AspectJ 컴파일러가 일반 .java파일을 컴파일할 때 부가기능을 넣어서 .class 파일로 컴파일해주는 것을 의미한다. → 이 동작을 위빙 이라고 부른다.
  2. 클래스 로딩 시점 적용
    • .class 파일을 올리는 시점에 바이트 코드를 조작해 AOP를 적용하는 방식이다.
  3. 런타임 시점 적용
    • 앱이 실행된 이후에 적용하는 방식이다. 코드를 조작하기 어려워 스프링, 컨테이너, DI, 빈 등 여러 개념과 기능을 사용하여 프록시를 통해 부가 기능을 적용하는 방식이다.
    • 프록시는 메서드 실행 시점에서만 다음 타켓을 호출할 수 있기 때문에, 런타임 시점에 부가기능을 적용하는 방식은 메서드의 실행 지점으로 제한된다.

Spring AOP

Spring AOP는 런타임 시점에 적용하는 방식을 사용한다.

AOP 용어 및 개념

Aspect

  • 공통 기능
  • Advice + PointCut을 모듈화한 애플리케이션의 횡단 기능

Join Point

  • 애플리케이션 실행 흐름에서의 특정 포인트 (ex. 클래스 초기화, 메서드 호출, 예외 발생 등)
  • 한 마디로 AOP를 적용할 수 있는 모든 지점 (스프링에서는 메서드 실행 지점으로 제한)

Advice

  • JoinPoint에서 실행되는 코드 즉 부가기능 그 자체
  • Aspect를 언제 핵심 코드에 적용할지 정의
Type설명
Before조인포인트 실행 이전에 실행, 일반적으로 리턴타입 void
After returning조인포인트 완료후 실행 (ex. 메서드가 예외없이 실행될 때)
After Throwing메서드가 예외를 던지는 경우 실행
After (finally)조인포인트의 동작과 관계없이 실행
Around메서드 호출 전후에 수행(조인포인트 실행 여부 선택, 반환 값 변환, 예외 변환, try~catch~finally 구문 처리 가능 등), 가장 강력한 어드바이스이다.

PointCut

  • JoinPoint 중 Advice가 적용될 지점을 선별하는 기능
  • 주로 AspectJ 표현식으로 지정

Target

→ 객체

  • 핵심 기능을 담은 모듈
  • Advice를 받는 객체, PointCut으로 결정된다. ( 조인포인트를 지정하면 되는 건가? )
    • 예를 들어, AOP를 통해 UserService 클래스의 메서드에 애스펙트를 적용한다면, TargetUserService 객체가 됩니다.

Advisor

  • 스프링 AOP에서만 쓰는 용어로, 하나의 Advice와 하나의 PointCut으로 구성된 Aspect를 특별하게 지칭하는 말이다.

결론

지금까지 3가지의 공통 기능 분리 방법을 알아보았다. 각 방법에는 장단점이 있었는데 모두 비슷한 장점과 단점이 존재했다. 장점으로는 개발자의 편리성 증진과 유지보수가 수월해진다는 것이다.(각 방법을 잘 알고 있다면...)
단점으로는 매 요청이 올때마다 이러한 추가적인 기능이 실행된다. 이 기능들은 주로 기존의 흐름에서 가로채기 때문에 많은 요청이 있을 때 성능이 저하될 수 있다. 그래서 성능이 저하되지 않게 필요한 곳에 적용하며 로직을 성능에 영향을 크게 주지 않게 작성해야겠다.
각 공통 기능에서 분리하는 방법은
Filter → 로그인 인증
Intercepter → 예외 처리
AOP → 로깅, 트랜잭션 관리
이렇게 적용할 계획이다. 이전의 프로젝트에서 필터가 적용된 코드 본 적이 있기에 빠르게 적용할 수 있겠지만 Intercepter와 AOP는 다뤘던 기억이 가물가물하기 때문에 새로운 느낌이 들어 기대가 된다.
끝.

profile
김김동현

0개의 댓글