토비 스프링 책을 탐구하며 스프링의 3요소 중 하나인 AOP에 대해 공부하는데 문뜩 Spring에서는 AOP말고 어떠한 로직을 실행되기 전 전처리 작업으로 지정할 수 있는 기능으로 Filter, 인터셉터도 있는데 AOP와의 역할의 차이에 대해 궁금하였다.
그래서 Spring MVC 생명주기 구조를 보며 흐름과 필터, 인터셉터, AOP의 대해 알아보고 그 내용에 대해 포스팅해보았다.

간단히 실행순서는 이렇게 진행된다.
Filter → InterCeptor → AOP → Interceptor → Filter
Filter (필터)
Filter는 '거르다' 라는 뜻을 가지고 있는데 무엇을 걸러내는 것일까?
위의 그림에서와 같이 Filter는 DispatcherServlet 앞에 존재한다. Spring context 외부에 존재하며, Spring과 무관한 자원에 대해 동작한다. 즉, 클라이언트의 요청과 응답에 대해 거른 뒤 변경 및 조작하는 역할을 한다.
예를들어, Spring과는 관련 없는 서블릿 기반의 웹 애플리케이션에서 파일 업로드 요청을 가로채고, 요청에 대한 처리와 파일 저장을 말할 수 있다.

- HTTP 요청 및 응답을 가로채어 처리하는 컴포넌트로,
위의 그림과 같이 Filter Chain(필터 체인)을 통해 여러 필터가 연쇄적으로 동작이 가능하다. - 사용자의 모든 요청은 필터를 거친다.
- DispatcherServlet 전/후 ServletRequest와 ServletResponse 객체 변경 및 조작 수행이 가능하다.
- WAS 웹 컨텍스트에서 실행된다. (servlet 단위에서 실행)
- 일반적으로 web.xml에 설정한다.
web.xml은 웹 어플리케이션 서버(WAS)가 최초로 구동 될 때 각종 설정을 정의한다.
설정태그는 Filter 외에도 세션의 유효시간 설정,서버의 root주소 설정 후 페이지접근설정, 에러페이지 설정 등
가능한 설정들이 많다.
설정파일만 수정해주는 것만으로도 어플리케이션 전체에 적용이 되고, 재컴파일 없이 바로 적용이 가능하다. - 요청에 대한 인증 및 권한 부여, 로깅, 보안 관련 공통 작업, 이미지/데이터 압축 및 문자열 인코딩에 사용된다.
ex) 인코딩, XSS방어 등..
XSS(Cross-Site Scripting ) 방어란? 웹 상에서 가장 기초적인 취약점 공격 방법중 하나로,
권한이 없는 사용자가 악의적인 용도로 웹 사이트에 스크립트를 삽입하는 공격 기법을 말한다.
다른 웹사이트와 정보를 교환하는 식으로 작동하므로 사이트 간 스크립팅이라고 부른다.
웹 애플리케이션이 사용자로부터 입력 받은 값을 제대로 검사하지 않고 사용할 경우 나타나며, 공격에 성공하면 사이트에 접속한 사용자는 삽입된 코드를 실행하게 되어, 의도치 않은 행동을 수행시키거나 쿠키나 세션 토큰 등의 민감한 정보를 탈취합니다. (참고자료)
Ex)
<!-- web.xml 설정 : 인코딩 -->
<filter>
<filter-name>encodingFilter</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>encodingFilter</filter-name>
<url-pattern>/*</url-pattern>
</filter-mapping>
<!-- 세션의 유효시간 설정 : 단위는 분, 30분 유효시간 설정 -->
<session-config>
<session-timeout>30</session-timeout>
</session-config>
<!-- 서버의 root주소 설정 -->
<welcome-file-list>
<welcome-file>/WEB-INF/jsp/index.jsp</welcome-file>
</welcome-file-list>
<!-- 에러페이지 설정 -->
<error-page>
<exception-type>java.lang.Throwable</exception-type>
<location>/WEB-INF/jsp/error/error.jsp</location>
</error-page>
<error-page>
<error-code>404</error-code>
<location>/WEB-INF/jsp/error/404.jsp</location>
</error-page>
<error-page>
<error-code>500</error-code>
<location>/WEB-INF/jsp/error/500.jsp</location>
</error-page>
Filter는 3가지의 메소드를 갖고 있는데 아래와 같다.
- init() : 필터가 웹 컨테이너에 생성될 때 실행
- doFilter : Request, Response가 필터를 거칠 때 수행되는 메소드로, 체인을 따라 다음 존재하는 필터로 이동
- destroy : 필터가 소멸될 때 실행
public interface Filter {
public default void init(FilterConfig filterConfig) throws ServletException {}
public void doFilter(ServletRequest request, ServletResponse response,
FilterChain chain) throws IOException, ServletException;
public default void destroy() {}
}
Interceptor(인터셉터)
Interceptor는 '가로채다'의 뜻을 가지고 있다. Filter와는 다른 무엇을 가로챌까?
위의 그림을 보면 인터셉터는 스프링 영역에 존재한다. 즉, 스프링 프레임워크에서 제공하는 기능이다.
DispatcherSerlvet 이 Controller 를 호출하기 전과 후로 특정 동작을 수행할 때 사용한다.
그래서 Spring Context 내부에서 컨트롤러의 요청과 응답에 대해 모든 Bean에 접근하여 처리한다.
- Spring Context에서 실행된다. (컨트롤러 단위에서 적용)
- 일반적으로 servlet-context.xml에 설정한다.
웹 어플리케이션에서 클라이언트의 요청을 받기 위한 컨텍스트 설정으로, 요청과 관련된 객체를 정의한다.
URL과 관련된 Controller, Annotation, ViewResolver,Interceptor 등의 설정을 해준다. - HandlerInterceptor 인터페이스를 구현, HandlerInterceptorAdaptor 클래스를 상속 받는 2가지 방법이 있다.
- 예외 발생 시, @ControllerAdvice에서 @ExceptionHandler를 사용해서 예외 처리한다.
- 컨트롤러 메서드 호출 전에 인증 및 권한 부여, 로깅 기능을 추가 할 수 있다
ex) 로그인 및 권한 체크, 프로그램 실행 시간 계산작업, 로그 확인 등..
Ex)
<!-- context.xml -->
<beans xmlns="http://www.springframework.org/schema/beans"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://www.springframework.org/schema/beans
http://www.springframework.org/schema/beans/spring-beans.xsd">
<!-- Interceptor 설정 -->
<mvc:interceptors>
<!-- Interceptor 빈 등록 -->
<bean class="com.example.MyInterceptor" />
</mvc:interceptors>
<!-- 다른 설정들.. -->
<!-- 어노테이션(@) 사용을 가능하게 한다. (기본값) -->
< annotation-driven / >
<!-- ViewResolver : view 실행단계에서 xml에서 등록된 viewResolver를 참조한다.
JSP와 name을 매핑시켜주는 태그로,
서블릿 설정으로 prefix(접두사) 와 suffix(접미사)를 붙여서 경로 설정한다.
사용자가 일일이 전체경로와 .jsp 를 붙이지 않아도 된다!
-->
<beans:bean class="org.springframework.web.servlet.view.InternalResourceViewResolver">
<beans:property name="prefix" value="/WEB-INF/views/" />
<beans:property name="suffix" value=".jsp" />
</beans:bean>
<!-- 해당 패키지에 있는 파일들의 어노테이션을 스캔해서 bean으로 등록하는 역할한다. -->
<context:component-scan base-package="com.패키지명1.패키지명2" />
<context:component-scan base-package="com.패키지명1.controller" />
<context:component-scan base-package="com.패키지명1.service" />
<context:component-scan base-package="com.패키지명1.dao" />
</beans>
Interceptor는 3가지의 메소드를 갖고 있는데 아래와 같다.
- preHandler() : 컨트롤러 메서드가 실행되기 전
- postHandler() : 컨트롤러 메서드 실행 직후 view페이지 렌더링 되기 전
- afterCompletion() : view페이지 렌더링 되고 난 후
public interface HandlerInterceptor {
default boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler)
throws Exception {
return true;
}
default void postHandle(HttpServletRequest request, HttpServletResponse response, Object handler,
@Nullable ModelAndView modelAndView) throws Exception {
}
default void afterCompletion(HttpServletRequest request, HttpServletResponse response, Object handler,
@Nullable Exception ex) throws Exception {
}
}
Filter 와 Interceptor 차이 및 용도 비교

AOP (Aspect Oriented Programming)
OOP를 보완하기 위해 나온 개념으로, 객체 지향의 프로그래밍을 했을 때 인터셉터 대신에
컨트롤러들에게 적용할 부가기능을 어드바이스로 만들어 AOP를 적용할 수 있다.
- 메서드 앞에서 Proxy 패턴의 형태로 실행한다. (메서드 단위 또는 클래스 전체에 걸쳐 적용)
- 부가기능(로깅, 트랜잭션 관리, 보안 등)을 모듈화하여 재사용 가능하게 사용한다.
- AspectJ나 @Aspect 어노테이션을 활용하여 구현한다.
결국 큰 차이점은 동작 위치가 다르다는 것!!!
- Filter : WAS 웹 컨텍스트에서 실행
- Interceptor : 스프링 컨텍스트에서 실행
- AOP : 메서드 앞에 Proxy 패턴의 형태로 실행
'Spring' 카테고리의 다른 글
| 스프링 의존성 주입(DI) - 생성자 주입/수정자 주입/필드 주입 (0) | 2023.09.22 |
|---|---|
| Log4j & Logback & Log4j2의 차이 (0) | 2023.08.25 |
| Mapper(Mybatis 라이브러리)를 활용한 DB와의 통신 (0) | 2023.06.26 |
| Spring Bean Scope란? (0) | 2023.06.18 |
| Spring AOP vs AspectJ (0) | 2023.05.23 |