Java Web 프로그래밍을 구현해 보면 공통 업무를 추가해야 하는 경우가 많다.
공통의 업무에는 로그인 처리(세션 체크), pc웹과 모바일 웹의 분기, 로그 확인, 페이지 인코딩 변환, 권한 체크, XSS(Cross site script) 방어 등이 있다.
이들 공통 작업과 관련된 코드를 모든 페이지별로 작성해야 하는 경우에는 코드가 겹쳐집니다.
프로젝트 단위가 커질수록 서버에 부하를 줄 수도 있고 소스 제어도 할 수 없다.
.
즉, 공통 부분은 빼고 따로따로 관리하는 것이 좋다.
이러한 공통 업무를 프로그램 흐름 전, 중간, 후에 추가하여 자동으로 처리할 수 있는 방법이 있으며, 관련 콘텐츠를 게시하려고 합니다.
위와 같은 공통 처리를 위해 활용할 수 있는 3가지가 있습니다.
1. Filter
2. Interceptor
3. AOP
스프링에 사용되는 Filter, Interceptor, AOP의 세 가지 기능은 모두 어떤 작업을 수행하기 전에 먼저 수행할지, 실행한 후 추가 작업을 수행할 때 사용되는 기능입니다.
이제 요청에 따라 필터, 인터셉터 및 AOP의 차이점에 대해 알아보겠습니다.
1. Filter, Interceptor, AOP 흐름
Filter, Interceptor, AOP 실행 절차
위의 그림을 보면 필터와 인터셉터의 차이를 구별할 수 있습니다.
작업 처리를 위해 컨트롤러가 실행되기 전에 사용한다는 점에서 그다지 차이가 보이지 않지만 흐름을 보면 명확하게 호출되는 시점이 다릅니다.
Interceptor와 Filter는 서블릿 단위로 실행됩니다.
반면에 AOP는 메소드 앞에 프록시 패턴 형태로 실행됩니다.
실행 순서를 보면 Filter가 가장 밖에 있고 그 안에 Interceptor, 그 안에 AOP가 있는 형태다.
따라서 요청이 들어오면 Filter→Interceptor→AOP→Interceptor→Filter 순으로 통과하게 된다.
실행되는 메소드를 기반으로 다시 설명하면,
1. 서버를 실행하고 서블릿이 올라가는 동안 init가 실행되고 doFilter가 실행됩니다.
2. 컨트롤러에 들어가기 전에 preHandler가 실행됩니다.
3. 컨트롤러에서 나와 postHandler, after Completion, doFilter로 이동합니다.
4. 서블릿 종료시에 디스트로이가 실행된다.
2. Filter, Interceptor, AOP 개념
Filter(필터)
말 그대로 요청과 답변을 하고 정제하는 역할을 한다.
서블릿 필터는 DispatcherServlet 이전에 실행되지만 필터가 작동하도록 지정된 리소스의 시작 부분에서 요청 내용을 변경하거나 다양한 검사를 수행할 수 있습니다.
또한, 리소스의 처리가 종료된 후, 응답 내용에 대해서도 변경하는 처리를 행할 수 있다.
필터는 web.xml에 등록하는데 대표적으로 인코딩 변환, 로그인 가부 확인, 권한 체크, XSS 방어 등의 요구에 대한 처리로서 사용된다.
<!
-- 한글 처리를 위한 인코딩 필터 -->
<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>
해당 필터의 이름은 인코딩이고 값은 UTF-8의 매개 변수를 정의합니다.
필터를 /*에 매핑하면 필터가 servlet, jsp뿐만 아니라 이미지와 같은 모든 리소스의 요청에도 호출된다는 것을 의미합니다.
필터 실행 방법
- init() – 필터 인스턴스 초기화
- doFilter() – 전/후 처리
- destroy() – 필터 인스턴스 종료
Interceptor(인터셉터)
요청에 대한 작업 전후에 가로챌 것으로 보면 된다.
앞서 언급했듯이 필터와 인터셉터는 호출 시점이 다릅니다.
필터는 스프링에 관계없이 지정된 자원에 대해 작동합니다.
Spring은 DistpatcherServlet에서 시작하므로 필터는 Spring 컨텍스트 외부에 있습니다.
그러나 인터셉터는 Spring의 DistpatcherServlet이 컨트롤러를 호출하기 전과 후에 인터럽트되기 때문에 Spring 컨텍스트 내에 존재합니다.
그리고 스프링의 모든 오브젝트 액세스가 가능합니다.
인터셉터는 복수를 사용할 수 있고, 로그인 체크, 권한 체크, 프로그램 실행 시간 계산 작업 로그 확인, 업로드 파일 처리 등에 사용된다.
인터셉터 실행 방법
- 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 : 타겟 메소드의 실행 전후
3. 정리
실행 장소 | 서블릿 | 서블릿 | 방법 |
실행 순서 | 1 | 2 | 3 |
설정 위치 | web.xml | xml or java | xml or java |
실행 방법 | init(), doFilter(), destroy() | preHandler(), postHanler(), afterCompletion() | 포인트 컷에서 @After, @Before, @Around의 위치 지정 |
메모