💡개념 들어가기 전에 =3
개발을 하다 보면 공통적으로 처리해야 할 업무들이 많음
공통 업무에 관련된 코드를 페이지마다 작성한다면 중복 코드가 많아지게 되고,
프로젝트 단위가 커질수록 서버에 부하를 줄 수도 있으며, 소스 관리도 되지 않음
이에 Spring은 공통적으로 여러 작업을 처리함으로써 중복된 코드를 제거할 수 있는 다음과 같은 기능들을 지원하고 있음 !
1. Filter
- 핸들러 동작의 전 후 과정에 부가로직 처리, 웹 컨테이너에서 관리
2. Interceptor
- 이하 비슷함, 스프링 컨테이너에서 관리
3. AOP (Aspect Oriented Programming, 관점 지향 프로그래밍)
- 메서드 동작의 전 후 과정에 부가로직 처리


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() {}
init()
필터 객체를 초기화하고 서비스에 추가하기 위한 메소드
웹 컨테이너가 1회 init()을 호출하여 필터 객체를 초기화하면 이후 요청들은 doFilter()를 통해 처리됨
doFilter()
url-pattern에 맞는 모든 HTTP 요청이 디스패처 서블릿으로 전달되기 전에 웹 컨테이너에 의해 실행되는 메소드
doFilter의 파라미터로 FilterChain이 있는데, FilterChain의 doFilter 통해 다음 대상으로 요청을 전달할 수 있게 됨
chain.doFilter()로 전, 후에 우리가 필요한 처리 과정을 넣어줌으로써 원하는 처리를 진행할 수 있음
destroy()
필터 객체를 제거하고 사용하는 자원을 반환하기 위한 메소드
웹 컨테이너가 1회 destroy()를 호출하여 필터 객체를 종료하면 이후에는 doFilter에 의해 처리되지 않음
필터에서는 기본적으로 스프링과 무관하게 전역적으로 처리해야 하는 작업들을 처리함
💡아래와 같은 처리에 적합
- 공통된 보안 및 인증/인가 관련 작업(XSS방어)
- 이미지/데이터 압축 및 문자열 인코딩 변환 처리
- Spring과 분리되어야 하는 기능
- 모든 요청에 대한 로깅
대표적으로 필터(Filter)를 인증과 인가에 사용하는 도구로는 SpringSecurity가 있음
SpringSecurity의 특징 중 하나는 Spring MVC에 종속적이지 않다는 것인데, 이러한 이유로는 필터 기반으로 인증/인가 처리를 하기 때문

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 {
}
preHandle()
Controller가 호출되기 전에 실행
컨트롤러 이전에 처리해야 하는 전처리 작업이나 요청 정보를 가공하거나 추가하는 경우에 사용할 수 있음
postHandle()
Controller가 호출된 후에 실행 ( View 렌더링 전)
컨트롤러 이후에 처리해야 하는 후처리 작업이 있을 때 사용할 수 있음
이 메소드는 컨트롤러가 반환하는 ModelAndView 타입의 정보가 제공되는데, 최근에는 JSON 형태로 데이터를 제공하는 RestAPI 기반의 컨트롤러(@RestController)를 만들면서 자주 사용되지 않음
afterCompletion()
모든 뷰에서 최종 결과를 생성하는 일을 포함해 모든 작업이 완료된 후에 실행 ( View 렌더링 후)
요청 처리 중에 사용한 리소스를 반환할 때 사용할 수 있음
인터셉터에서는 클라이언트의 요청과 관련되어 전역적으로 처리해야 하는 작업들을 처리함
💡아래와 같은 처리에 적합
- 세부적인 보안 및 인증/인가 공통 작업
- API 호출에 대한 로깅 또는 감사
- Controller로 넘겨주는 정보(데이터)의 가공
AOP는 핵심 비즈니스 로직에 있는 공통 관심사항을 분리하여 각각을 모듈화 하는 것
공통 모듈인 인증, 로깅, 트랜잭션 처리에 용이
AOP의 가장 큰 특징이자 장점은 중복 코드 제거, 재활용성의 극대화, 변화수용의 용이성이 좋다는 것
즉 URL 기반이 아닌 PointCut 단위로 동작
이 때문에 비즈니스 로직의 메서드 실행 전, 후 단위까지 핸들링 할 수 있음

ex)
결제+로깅, 게시판+로깅, 유저+로깅
AOP로 처리하면
로깅() 메서드를 따로 만들어 놓고, 어노테이션으로 등록한 후에,
결제(), 게시판(), 유저() 메서드 위에 '@로깅' 한줄만 붙이기
=> 기존 코드에서 관심사가 분리되었으니 유지보수 easy
자세한 개념 -> https://sallykim5087.tistory.com/158
필터는 Request와 Response를 조작할 수 있지만, 인터셉터는 조작할 수 없음
필터의 경우 웹 컨텍스트 안에서 실행
인터셉터의 경우 스프링 컨텍스트 안에서 실행

인터셉터 대신에 컨트롤러들에 적용할 부가기능을 어드바이스로 만들어 AOP를 적용할 수도 있음
하지만 다음과 같은 이유들로 컨트롤러의 호출 과정에 적용되는 부가기능들은 인터셉터를 사용하는 편이 나음
즉, 타입이 일정하지 않고 호출 패턴도 정해져 있지 않기 때문에 컨트롤러에 AOP를 적용하려면 번거로운 부가 작업들이 생기게 됨