Cross-Cutting Concerns를 처리하는 방법
많은 로직에서 공통으로 관심이 있는 부분을 공통 관심사 라고 한다.
로그인 같은 것이 한 예시이다. 로그인이 필요한 모든 컨트롤러 로직에 로그인 여부를 확인하는 코드를 넣는 것은 너무 비효율적이기 때문에, 이런 공통 관심사를 처리해줄 방법이 필요하다.
cross-cutting concerns를 처리하는 방법은 filter, interceptor, aop 등이 있다.
그 중에서도 web에 관련된 공통 관심사는 AOP 보다는 servlet filter, spring interceptor에서 처리하는 것이 좋다.
웹과 관련된 공통 관심사를 처리할 때는 HTTP의 헤더나 URL 정보가 필요한데 서블릿 필터나, 스프링 인터셉터는 HttpServletRequest를 제공하기 때문이다.
Servlet Filter & Spring Interceptor
둘은 위치에 차이가 있다.
서블릿을 기준으로 filter는 앞 쪽에, interceptor는 뒤 쪽에 위치한다.
서블릿 필터
J2EE 표준 스펙 기능.
Dispatcher Servlet에 요청이 전달되기 전/후에 url 패턴에 맞는 모든 요청에 대해 부가작업을 처리할 수 있는 기능을 제공함.
웹 컨테이너(서블릿 컨테이너)에 의해 관리가 됨.
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() {}
}
Filter 인터페이스를 구현한 뒤 등록하면 서블릿 컨테이너가 필터를 등록 후 싱글톤 객체를 생성 및 관리한다.
인터셉터
Spring이 제공하는 기술로써, Dispatcher Servlet이 컨트롤러를 호출하기 전과 후에 요청과 응답을 참조하거나 가공할 수 있는 기능을 제공함.
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 {
}
}
컨트롤러단에서 예외 발생 시 postHandle 메서드는 호출되지 않는다.
afterCompletion 메서드는 예외 발생 여부와는 상관없이 항상 호출된다.
따라서, 예외처리가 필요하다면 afterCompletion에서 수행해주어야한다.
요약
Reference
'Backend > Spring Boot' 카테고리의 다른 글
VO, Entity, DTO, DAO (0) | 2024.03.10 |
---|---|
IoC 컨테이너 & DI (0) | 2024.03.10 |
Spring Boot (0) | 2024.03.10 |
Servlet (0) | 2024.03.10 |