웹개발/egov

[egov] Filter, Interceptor, AOP 차이점 및 사용법

08genie 2023. 4. 8. 14:06
반응형

Filter, Interceptor, AOP의 흐름

filter, interceptor, aop 흐름

요청이 들어오면 Filter Interceptor →  AOP → Interceptor → Filter 순으로 거치게 됩니다.

 

1. 서버를 실행시켜 서블릿이 올라오는 동안에 init이 실행되고, 그 후 doFilter가 실행됩니다.

2. 컨트롤러에 들어가기 전 Interceptor의 preHandler가 실행됩니다.

3. 컨트롤러에서 나오면 postHandler after Completion doFilter 순으로 실행됩니다.

4. 서블릿 종료 시 destroy가 실행됩니다.

 


Filter(필터)

Filter는 말 그대로 어떤 것을 걸러내는 역할을 합니다. 위 흐름에서 보면 DispatcherServlet 앞에 Filter가 존재하는 것을 볼 수 있습니다. 즉, 클라이언트의 요청에 대해 사전에 걸러내는 역할을 합니다. 또한 Response를 줄 때도 변경 처리를 할 수 있다는 특징을 가지고 있습니다.

ex) CORS, XSS 방어, 인코딩 변환 등

  • init(): 필터 인스턴스 초기화
  • doFilter(): 전/후 처리
  • destroy(): 필터 인스턴스 종료
package egovframework.example.filters;

import java.io.IOException;

import javax.servlet.Filter;
import javax.servlet.FilterChain;
import javax.servlet.FilterConfig;
import javax.servlet.ServletException;
import javax.servlet.ServletRequest;
import javax.servlet.ServletResponse;

import org.springframework.stereotype.Component;

@Component
public class FilterTest implements Filter {//Filter 인터페이스를 implements 하여 사용

    @Override
    public void init(FilterConfig filterConfig) throws ServletException {
        System.out.println("Filter init");
    }

    @Override
    public void doFilter(ServletRequest request, ServletResponse response, FilterChain chain) throws IOException, ServletException {
        System.out.println("do Filter");
        //이전 필터의 정보를 받아오며, 다음의 필터 또는 리소스를 호출하는 역할을 합니다.
        chain.doFilter(request, response);
    }

    @Override
    public void destroy() {
        System.out.println("Filter Destroy");
    }
}

 

해당 필터 클래스 빈등록 (web.xml)

<?xml version="1.0" encoding="UTF-8"?>
 ... 생략 
 
    <filter>
        <filter-name>filterTest</filter-name>
        <filter-class>com.example.filters.FilterTest</filter-class>
    </filter>
    
    <filter-mapping>
        <filter-name>filterTest</filter-name>
        <url-pattern>*.do</url-pattern>
    </filter-mapping>
    
... 생략

 


Interceptor(인터셉터)

필터는 스프링 영역 외부에 존재하여 스프링과 무관한 자원에 대해 동작하지만 인터셉터는 스프링 영역 안에서 실행되는 것으로 스프링의 DistpatcherServlet이 컨트롤러를 호출하기 전, 후로 끼어들기 때문에 스프링 영역 내부에서 Controller(Handler)에 관한 요청과 응답에 대해 처리합니다.

  • preHandle: 컨트롤러가 실행되기 전에 호출되는 메서드
  • postHandle: 컨트롤러가 실행된 후, 뷰가 렌더링 되기 전에 호출되는 메서드
  • afterCompletion: 뷰가 렌더링된 후에 호출되는 메서드
package egovframework.example.interceptors;

import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;

import org.springframework.web.servlet.HandlerInterceptor;
import org.springframework.web.servlet.ModelAndView;

public class InterceptorTest implements HandlerInterceptor { //HandlerInterceptor 클래스를 implements 하여 사용
    @Override
    public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler) throws Exception {
        System.out.println("preHandle() method is called");
        return true; // 컨트롤러를 실행합니다.
    }ㅇ

    @Override
    public void postHandle(HttpServletRequest request, HttpServletResponse response, Object handler, ModelAndView modelAndView) throws Exception {
        System.out.println("postHandle() method is called");
    }

    @Override
    public void afterCompletion(HttpServletRequest request, HttpServletResponse response, Object handler, Exception ex) throws Exception {
        System.out.println("afterCompletion() method is called");
    }
}

 

해당 인터셉터 클래스 빈등록 (dispatcher-servlet.xml)

<?xml version="1.0" encoding="UTF-8"?>
... 생략

    <mvc:interceptors>
    	<bean class="egovframework.example.interceptors.InterceptorTest" />
    </mvc:interceptors>

... 생략

 


AOP

AOP는 Aspect Oriented Programming의 약자로 관점 지향 프로그래밍이라고 불립니다.  관점 지향은 어떤 로직을 기준으로 핵심적인 관점, 부가적인 관점으로 나누어서 보고 그 관점을 기준으로 어떤 공통된 로직이나 기능을 하나의 단위로 묶어 모듈화 하겠다는 것입니다.

주로 로깅, 트랜잭션, 에러 처리 등 비즈니스단의 메서드에서 조금 더 세밀하게 조정하고 싶을 때 사용합니다.

Interceptor나 Filter와는 달리 메소드 전후의 지점에 자유롭게 설정이 가능하고 Interceptor와 Filter는 주소로 대상을 구분해서 걸러내야하는 반면,  AOP는 주소, 파라미터, 애노테이션 등 다양한 방법으로 대상을 지정할 수 있습니다.

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

import org.aspectj.lang.JoinPoint;

public class AspectTest {
	
    public void beforeAdvice(JoinPoint joinPoint) {
        System.out.println("Before Advice : " + joinPoint.getSignature().getName());
    }
}

 

해당 AOP 클래스 빈등록 (dispatcher-servlet.xml)

<?xml version="1.0" encoding="UTF-8"?>
... 생략

    <aop:config>
        <aop:aspect ref="aspectTest">
            <aop:pointcut expression="execution(* egovframework.example.sample.web.*.*(..))" id="controllerMethods"/>
            <aop:before method="beforeAdvice" pointcut-ref="controllerMethods"/>
        </aop:aspect>
    </aop:config>

... 생략
💡 <aop:config> 에러가 난다면  아래와 같이 Namespaces 탭에서  aop를 체크해주세요.
namespaces aop 설정

 

Reference : https://goddaehee.tistory.com/154
https://devlog-wjdrbs96.tistory.com/352

반응형