T_era

공통 관심사(Cross-Cutting Concerns)와 Servlet Filter 본문

Programing/Spring

공통 관심사(Cross-Cutting Concerns)와 Servlet Filter

블스뜸 2025. 5. 15. 13:48

공통 관심사 (횡단 관심사)

  • 여러 코드 영역에서 공통적으로 사용되는 부가적인 기능.
  • Filter는 공통 관심사 처리를 위해 등장함.

핵심 기능 vs 부가 기능

  • 핵심 기능: 애플리케이션의 주된 목적 수행 (CRUD 등).
  • 부가 기능: 핵심 기능에 추가적인 기능 제공 (로깅, 보안, 인증 등).

예시: 로그인 사용자만 특정 API 접근 허용 요구사항

  • Controller마다 로그인 확인 로직 반복 시 코드 중복 및 유지보수 어려움 발생.
@RestController
@RequestMapping("/post")
public class PostController {
    @PostMapping
    public PostResponseDto create(PostCreateRequestDto request) {
        // 로그인 여부 확인 로직 (공통 관심사)
        // 생성 로직 (핵심 기능)
    }

    @PutMapping("/{postId}")
    public void update(
            @PathVariable Long postId, PostUpdateRequestDto request
    ) {
        // 로그인 여부 확인 로직 (공통 관심사)
        // 수정 로직 (핵심 기능)
    }

    @DeleteMapping("/{postId}")
    public void delete(@PathVariable Long postId) {
        // 로그인 여부 확인 로직 (공통 관심사)
        // 삭제 로직 (핵심 기능)
    }
}

Servlet Filter

  • 공통 관심사 로직 중앙 집중화로 재사용성 및 유지보수성 향상.
  • 모든 요청을 단일 진입점으로 처리하여 일관성 유지.
  • HTTP 요청 및 응답 필터링 기능 제공.
  • Filter Chain: 여러 필터 순차적 적용 가능, filterChain.doFilter()로 제어 전달.
  • doFilter(): 필터링 작업 정의, 다음 필터 호출 여부 결정.
  • Servlet 호출 전 Filter 항상 경유.
  • 특정 URL 패턴에 Filter 적용 가능.
  • Spring 환경에서 Servlet은 Dispatcher Servlet.
  • Filter Chain: 개발자 자유롭게 추가 및 순서 지정 가능.

Filter Interface (jakarta.servlet.Filter)

  • HTTP 요청 및 응답 가로채고 처리하는 인터페이스.
  • Servlet Container에 의해 싱글톤 객체로 관리.
  • 주요 메서드:
    • init(): 필터 초기화 시 호출 (default).
    • doFilter(ServletRequest request, ServletResponse response, FilterChain chain): 요청마다 호출되는 핵심 메서드. 필터 로직 구현 및 chain.doFilter() 호출 결정. HttpServletRequest로 다운 캐스팅하여 사용.
    • destroy(): 필터 종료 시 호출 (default).

Filter 구현체 예시 (요청 URL 로깅)

@Slf4j
public class CustomFilter implements Filter {
    @Override
    public void doFilter(
            ServletRequest request,
            ServletResponse response,
            FilterChain chain
    ) throws IOException, ServletException {

        HttpServletRequest httpRequest = (HttpServletRequest) request;
        String requestURI = httpRequest.getRequestURI();

        log.info("request URI={}", requestURI);
        chain.doFilter(request, response); // 다음 필터 또는 Servlet 호출
    }
}

Filter 등록

  • FilterRegistrationBean: Spring Boot에서 필터 등록, 순서, URL 패턴 설정.
  • setFilter(): 필터 구현체 설정.
  • setOrder(): 필터 실행 순서 지정 (낮을수록 우선순위 높음).
  • addUrlPatterns(): 필터 적용 URL 패턴 지정.
@Configuration
public class WebConfig implements WebMvcConfigurer {
    @Bean
    public FilterRegistrationBean customFilter() {
        FilterRegistrationBean<Filter> filterRegistrationBean = new FilterRegistrationBean<>();
        filterRegistrationBean.setFilter(new CustomFilter());
        filterRegistrationBean.setOrder(1);
        filterRegistrationBean.addUrlPatterns("/*"); // 모든 요청에 적용
        return filterRegistrationBean;
    }
}

Servlet Filter 정리

  • Filter 인터페이스 구현 후 @Bean 등록.
  • HTTP 요청 시 doFilter() 호출, HttpServletRequest로 다운 캐스팅.
  • chain.doFilter()를 통해 다음 필터 또는 Servlet 호출 (미호출 시 처리 중단).
  • FilterRegistrationBean으로 필터 순서 및 URL 패턴 설정하여 등록 (@WebFilter는 순서 제어 어려움).

결론적으로, Servlet Filter는 공통적인 부가 기능을 중앙에서 처리하여 코드 효율성 및 유지보수성을 향상시키는 메커니즘이다.