1. DispatcherHandler 소개
- Spring WebFlux의 DispatcherHandler는 Spring MVC의 DispatcherServlet과 유사한 역할을 하는 핵심 컴포넌트입니다.
- 두 프레임워크 모두 Front Controller 패턴을 기반으로 설계되었으며, 중앙 집중형 컴포넌트를 통해 요청을 처리합니다.
Front Controller 패턴이란?
Front Controller 패턴은 모든 웹 요청을 단일 진입점에서 처리하는 디자인 패턴입니다. 이 패턴의 주요 특징은:
- 모든 요청이 하나의 컨트롤러를 통과
- 요청에 대한 공통 처리 로직 중앙화
- 보안, 로깅, 라우팅 등의 횡단 관심사를 효율적으로 처리
- 뷰나 비즈니스 로직으로의 제어 흐름을 일관되게 관리
1.1 Front Controller 패턴 구현
- Spring MVC: DispatcherServlet이 모든 웹 요청의 진입점 역할
- Spring WebFlux: DispatcherHandler가 reactive 스택에서 같은 역할 수행
1.2 주요 특징
- 공유 알고리즘을 통한 요청 처리
- DispatcherHandler는 모든 요청에 대해 일관된 처리 알고리즘을 제공합니다.
- 위임 컴포넌트를 통한 실제 작업 수행
- 실제 비즈니스 로직의 처리는 각각의 전문화된 컴포넌트들에게 위임됩니다.
- 예를 들어, HandlerMapping은 요청 경로 분석을, HandlerAdapter는 실제 핸들러 실행을, HandlerResultHandler는 결과 처리를 담당합니다.
- 유연한 워크플로우 지원
- 각 단계별로 다양한 구현체를 제공하고 있어, 개발자는 자신의 요구사항에 맞는 컴포넌트를 선택하거나 직접 구현하여 사용할 수 있습니다.
- 예를 들어 @RequestMapping 기반의 핸들러뿐만 아니라 함수형 엔드포인트도 동일한 구조 내에서 처리할 수 있습니다.
- Spring 설정을 통한 위임 컴포넌트 자동 발견
- ApplicationContext를 통해 필요한 컴포넌트들을 자동으로 찾아 구성합니다.
- 개발자는 원하는 컴포넌트를 Bean으로 등록하기만 하면 되며, DispatcherHandler가 이를 자동으로 찾아 적절한 시점에 사용합니다.
2. 기본 아키텍처
2.1 WebFlux 애플리케이션의 주요 구성요소
Spring WebFlux 애플리케이션은 다음과 같은 주요 컴포넌트들로 구성됩니다
- webHandler라는 빈 이름을 가진 DispatcherHandler: 모든 웹 요청의 진입점으로, 전체 요청 처리 과정을 조율합니다.
- WebFilter와 WebExceptionHandler
- WebFilter는 요청이 DispatcherHandler에 도달하기 전에 가장 먼저 동작합니다
- 인증, 로깅, CORS 처리 등 공통적인 전처리 작업을 수행합니다
- 필터 체인을 통해 순차적으로 실행되며, 각 필터는 다음 필터로 요청을 전달합니다
- WebExceptionHandler는 전체 처리 과정에서 발생하는 예외를 캐치하여 적절한 오류 응답을 생성합니다
- DispatcherHandler 전용 빈들의 협력 과정
- HandlerMapping이 요청 URL과 매칭되는 핸들러를 찾습니다
- 찾은 핸들러는 HandlerAdapter를 통해 실행됩니다
- 핸들러의 실행 결과는 HandlerResultHandler가 받아 최종 응답으로 변환합니다
- 자세한 내용은 아래에서 다루겠습니다.
2.2 요청 처리 체인 구성
ApplicationContext context = ...
HttpHandler handler = WebHttpHandlerBuilder.applicationContext(context).build();
이렇게 구성된 HttpHandler는 서버 어댑터와 함께 사용할 준비가 완료됩니다.
2.3 ServerWebExchange 이해하기
- ServerWebExchange는 Spring WebFlux에서 웹 요청-응답 교환을 나타내는 인터페이스입니다.
- 쉽게 말해 "HTTP 요청/응답과 관련된 모든 정보를 담고 있는 컨테이너"입니다.
- Spring MVC의 ServletRequest/ServletResponse와 유사한 역할을 하지만, 리액티브 스택에 맞게 설계되었습니다.
주요 특징과 역할
- 요청-응답 컨텍스트
- HTTP 요청과 응답에 대한 접근을 제공합니다
- 요청 처리에 필요한 추가 컨텍스트 정보를 포함합니다
- 세션 관리, 요청 속성, 경로 변수 등을 처리합니다
- 불변성 보장
- 모든 mutating 메서드는 새로운 ServerWebExchange 인스턴스를 반환합니다
- 이는 리액티브 프로그래밍의 불변성 원칙을 따릅니다
- 여러 스레드에서 안전하게 접근할 수 있습니다
주요 메서드와 기능
public interface ServerWebExchange {
// 요청 관련
ServerHttpRequest getRequest();
// 응답 관련
ServerHttpResponse getResponse();
// 세션 관리
Mono<WebSession> getSession();
// 요청 속성 관리
Map<String, Object> getAttributes();
// 경로 변수 접근
Map<String, String> getPathVariables();
// 폼 데이터 접근
Mono<MultiValueMap<String, String>> getFormData();
// 멀티파트 데이터 접근
Mono<MultiValueMap<String, Part>> getMultipartData();
}