Spring

GenericFilterBean vs OncePerRequestFilter

dev-rootable 2024. 4. 24. 14:08

📌 Overview

 

Spring Security와 JWT를 이용하여 토큰 기반 인증 구조를 구현하면서 GenericFilterBean과 OncePerRequestFilter로 구현한 코드를 보게 되었다. 그래서 두 방식의 차이점을 아래에서 비교해 보고자 한다.

 


 

🧾 Filter

 

https://velog.io/@jmjmjmz732002/Springboot-OncePerRequestFilter-vs-GenericFilterBean

 

위 그림은 Spring MVC에서 요청의 lifecycle을 나타낸 그림이다.

 

javax.servlet-api나 tomcat-embed-core를 사용하면 제공되는 Servlet Filter Interface로서 클라이언트의 서블릿 요청을 가장 먼저 받는다.

 

✅ Filter interface

 

package jakarta.servlet;

import java.io.IOException;

public interface Filter {
    default void init(FilterConfig filterConfig) throws ServletException {
    }

    void doFilter(ServletRequest request, ServletResponse response, FilterChain chain)
            throws IOException, ServletException;

    default void destroy() {
    }
}

 

🧾 GenericFilterBean

 

Spring에서 제공하는 확장된 Filter로서 Spring의 설정 정보를 가져올 수 있게 확장된 추상 클래스

 

public abstract class GenericFilterBean implements Filter, BeanNameAware, EnvironmentAware,
		EnvironmentCapable, ServletContextAware, InitializingBean, DisposableBean {

	/** Logger available to subclasses. */
	protected final Log logger = LogFactory.getLog(getClass());

	@Nullable
	private String beanName;

	@Nullable
	private Environment environment;

	@Nullable
	private ServletContext servletContext;

	@Nullable
	private FilterConfig filterConfig;

	private final Set<String> requiredProperties = new HashSet<>(4);
    
    ...

 

💥 문제점

 

Filter와 GenericFilterBean은 둘 다 매 서블릿마다 호출된다. 서블릿은 사용자의 요청을 받으면 서블릿을 생성해 메모리에 저장해 두고, 같은 클라이언트의 요청을 받으면 생성해 둔 서블릿 객체를 재활용하여 요청을 처리한다.

 

문제는 필터가 2번씩 적용되는 경우다.

 

Sample

 

일반적으로 Spring Security에서 인증과 접근 제어 기능이 Filter로 구현된다. 이러한 인증과 접근 제어 기능은 서블릿 간에 흐름을 동적으로 연결시켜주는 Dispatch가 이루어진다. 여기서 "API 1 Redirect"가 수행되는데, 결과적으로 다시 Filter chain을 거쳐 여러 번 인증처리가 수행되는 것이다. 이것은 한 번의 클라이언트 요청에 대해 흐름상 두 번 요청하게 되어
자원 낭비가 발생
하는 결과로 이어진다. 이러한 문제를 해결하기 위해서 OncePerRequestFilter가 등장했다.

 


 

🧾 OncePerRequestFilter

 

Spring에서 제공하는 확장된 Filter로서 모든 서블릿에서 일관된 요청을 처리할 수 있는 추상 클래스

 

해당 추상 클래스를 구현한 필터는 doFilterInternal 메서드를 구현하여 사용자의 요청 당 한 번만 실행되는 필터를 만들 수 있다.

 

@Slf4j
@Component
public class CustomFilter extends OncePerRequestFilter {

    @Override
    protected void doFilterInternal(HttpServletRequest request, HttpServletResponse response, FilterChain filterChain) throws ServletException, IOException {
        // TODO 전처리
        filterChain.doFilter(request , response);
        // TODO 후처리
    }
}

 

 

GenericFilterBean과 OncePerRequestFilter 둘 다 대상을 필터로 등록해 주는 인터페이스

 

Refences

 

https://velog.io/@jmjmjmz732002/Springboot-OncePerRequestFilter-vs-GenericFilterBean

 

[Springboot] OncePerRequestFilter vs GenericFilterBean

인증과 인가를 담당하는 Spring Security 알고 쓰자👀

velog.io

 

https://g4daclom.tistory.com/115

 

[스프링] GenericFilterBean과 OncePerRequestFilter의 차이

Spring Security와 JWT를 활용해서 회원 인증 기능을 구현하기 위해 여러 코드들을 보고 공부하던 중에 GenericFilter를 이용해 필터를 구현한 코드와 OncePerRequestFilter를 이용한 코드가 있어서 서로 어떤

g4daclom.tistory.com

 

https://velog.io/@dev_tmb/JWT-%ED%86%A0%ED%81%B0-%EC%9D%B8%EC%A6%9D-%ED%94%8C%EB%A1%9C%EC%9A%B0

 

Spring Security+JWT 토큰 인증 플로우

'엄빠도 어렸다' 프로젝트를 진행하며, 스프링 부트 서버에서 API 호출 시 Spring Security+JWT 토큰을 이용한 인증/인가의 구체적인 흐름을 파악하고자 공부한 내용입니다.

velog.io