Developer Cafe

Filter, Interceptor, AOP 차이 및 정리 본문

기술면접

Filter, Interceptor, AOP 차이 및 정리

개발자 카페 2024. 4. 29. 17:23
728x90
공통업무에 관련된 코드를 프로그램 흐름의 앞, 중간, 뒤에 추가하여
자동으로 처리할 수 있는 방법이 3가지가 있다.

FIlter, Interceptor, AOP

  • 요청이 들어오게 되면 request > Filter > Servlet > Interceptor > AOP > Controller순으로 실행됩니다.
  • DisptacherServlet, Interceptor, AOP, Controller Spring Context 속하고, Filter 경우에는 Web Context 속합니다.

Filter

  • 스프링의 독자적인 기능이 아닌 자바 서블릿에서 제공하는 기능
  • 스프링 컨텍스트가 아니라 컨텍스트에 속하며, 스프링 컨테이너가 아니라 웹컨테이너(톰캣) 의해 관리됩니다.
  • Filter FilterChain 통해 여러 필터가 연쇄적으로 동작하게 있습니다.
  • 주로 요청에 대한 권한, 인증을 처리하는데 사용합니다. EX) Spring Security, JWT 등등

필터 클래스는 servlet Filter 인터페이스(javax.servlet.Filter) 통해 구현할 있습니다.

@Slf4j
public class CustomFilter implements Filter {

    @Override
    public void init(FilterConfig filterConfig) throws ServletException {
        log.info("1. CustomFilter 실행");
        Filter.super.init(filterConfig);
    }


    @Override
    public void doFilter(ServletRequest request, ServletResponse response, FilterChain chain) throws IOException, ServletException {
        log.info(">>>>>>>>> 2. CustomFilter 동작 >>>>>>>>>");
        log.info(">>>>>>>>> 시작 >>>>>>>>>");
        chain.doFilter(request, response);
        log.info(">>>>>>>>> 종료 >>>>>>>>>");
    }

    @Override
    public void destroy() {
        log.info("3. CustomFilter 삭제");
        // Filter.super.destroy();
    }

 

1. init (필터가 생성될 때 수행되는 메소드)
: 웹 컨테이너가 사용 중인 필터를 나타내기 위해 호출됩니다. 서블릿 컨테이너틑 필터를 인스턴스화한 후 init 메서드를 정확히 한 번 호출합니다. 필터가 필터링 작업을 수행하도록 요청하기 전에 init 메소드는 성공적으로 완료되어야 합니다.

 

2. doFilter (request, response 가 필터를 지나갈 때 수행되는 메소드)
: 클라이언트의 요청이나 응답으로 인해 체인을 통과할 때마다 컨테이너에 의해 호출되는 메소드입니다. 이 메소드에 파라미터로 전달된 필터 체인은 필터가 요청과 응답을 다음 엔티티로 전달할 수 있도로 합니다.

 

3. destroy (필터가 종료될 때 수행되는 메소드)
: 필터의 doFilter 메서드 내의 모든 스레드가 종료되거나 시간 초과 시간이 지난 후에 웹 컨테이너에서 호출하며, 필터에 서비스가 중단되었음을 나타냅니다. 웹 컨테이너가 이 메서드를 호출한 다음에는 doFilter 메소드를 다시 호출하지 않습니다.

Interceptor

  • Interceptor는 Dispatcher Servlet이 Controller를 호출하기 전과 후에 요청과 응답을 가공하기 위해 사용한다.
  • Interceptor는 여러 개를 등록할 수 있으며, 순차적으로 인터셉터를 거친 후 Controller를 실행한다.
  • Filter와의 가장 큰 차이점은 스프링의 모든 빈 객체에 접근할 수 있다는 점이다. 추가로 Interceptor에서는 filter와는 다르게 트랜잭션과 관련된 처리도 진행할 수 있다.

주로 아래와 같은 작업에 적합하다.

 

1. 세부적인 보안 및 인증/인가 작업

2. API 호출에 대한 로깅 또는 검증

3. Controller로 넘겨주는 정보의 가공

 

package org.springframework.web.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 {
	}
    
}

 

preHandle은 핸들러 매핑에서 적절한 핸들러 객체를 결정한 후 핸들러 어댑터가 핸들러를 호출하기 전에 호출된다.

 

postHandle은 핸들러 어댑터가 실제로 핸들러를 호출한 후 Dispatcher Servlet이 view를 렌더링하기 전에 호출된다. 이 메소드를 사용할 땐 각 인터셉터는 실행 체인의 역순으로 실행을 처리한다.

 

afterCompletion은 요청 처리가 완료된 후, 즉 Interceptor의 preHandle 메소드가 성공적으로 완료되고 true가 반환된 경우에만 호출된다. postHandle과 마찬가지로 실행 체인의 역순으로 실행을 처리한다.

AOP

  • Spring AOP는 스프링 프레임워크에서 제공하는 기능으로, 애플리케이션에서 발생하는 특정 이벤트(메서드 호출, 예외 발생 등)에 대한 공통적인 기능(로깅, 트랜잭션 처리 등)을 적용할 수 있도록 해준다. 이를 통해 애플리케이션 전체에서 중복되는 코드를 줄이고, 유지/보수성을 향상시킬 수 있다.
  • Interceptor는 주로 Controller와 관련된 처리를 진행하는 반면, AOP는 세부적인 비즈니스 로직, 메소드와 관련된 처리를 진행하기 위해 사용된다.
  • Spring AOP는 자바의 프록시 패턴을 기반으로 만들어진다. 기존 클래스의 빈이 만들어질 때 프록시 객체를 자동으로 만들고 원본 객체 대신 프록시 객체를 빈으로 등록한다. (프록시 패턴은 가짜 객체를 생성하여 본 객체를 생성하는 시점을 최대한 늦추는 디자인 패턴이다.)
@Aspect    // Aspect 명시
@Component // 스프링 빈 등록
public class LogAspect {

    //로거 생성
    Logger logger = LoggerFactory.getLogger(LogAspect.class);

    // @Around("@annotation(LogExecutionTime)")
    @Around("execution(* velog.soyeon.spring.aop.*.*(..))") // 메소드 실행전후에 공통 로직을 적용할 때 사용
    public Object logExecutionTime(ProceedingJoinPoint joinPoint) throws Throwable{
        StopWatch stopWatch = new StopWatch();
        stopWatch.start();                      // 스탑워치 시작
        Object proceed = joinPoint.proceed();   // 메소드 실행
        stopWatch.stop();                       // 스탑워치 끝
        logger.info(stopWatch.prettyPrint());   // 로깅
        return proceed;
    }
}

 

@Around 는 메소드 실행 전/후에 공통 로직을 적용하고 싶을 떄 사용하고,

@Before 은 메소드 실행 전에 공통 로직을 적용하고 싶을 떄,

@After 메소드 실행 후에 공통 로직을 적용하고 싶을 사용합니다.

Pointcut 표현식 설명
execution(public * *(..)) public 메소드 실행
execution(* set*(..)) 이름이 set으로 시작하는 모든 메소드명 실행
execution(* com.xyz.service.TestService.*(..)) TestService 인터페이스의 모든 메소드 실행
execution(* com.xyz.service.*.*(..)) com.xyz.service 패키지의 모든 메소드 실행
bean(*Reepository) 이름이 "Repository" 끝나는 모든
728x90

'기술면접' 카테고리의 다른 글

웹개발자 기술면접 정리 6  (0) 2021.03.29
웹개발자 기술면접 정리 5  (0) 2021.03.29
웹개발자 기술면접 정리 4  (0) 2021.03.18
웹개발자 기술면접 정리 3  (0) 2021.03.18
웹개발자 기술면접 정리 2  (0) 2021.03.18
Comments