✅ Spring WebFlux의 핵심 구조: DispatcherHandler와 그 내부 구조
앞에서 @RestController와 @Component 방식의 차이를 다뤘다면, 이번에는 이 둘이 내부적으로 어떤 구조에서 동작하며, 왜 그 차이가 발생하는지를 정리해본다.
🔸 DispatcherHandler란?
DispatcherHandler는 Spring WebFlux의 중앙 진입점이다. Spring MVC에서의 DispatcherServlet과 역할이 동일하며, HTTP 요청을 받아 핸들러를 찾고 실행한 뒤 결과를 반환하는 흐름을 제어한다.
WebFlux는 논블로킹 환경에서 동작하기 때문에 DispatcherHandler도 내부적으로 Mono와 Flux를 사용해 모든 처리를 리액티브하게 실행한다.
🔸 RestController는 왜 DispatcherHandler를 타는가?
@RestController 기반의 API는 Spring이 자동 구성한 HandlerMapping과 HandlerAdapter에 등록된 정보에 따라 동작한다. 따라서 모든 요청은 반드시 DispatcherHandler를 경유하게 된다.
이 덕분에 다음과 같은 고수준 기능들을 사용할 수 있다:
- @Valid 등의 요청 검증
- @ControllerAdvice를 통한 전역 예외 처리
- @ModelAttribute, @RequestParam 자동 바인딩
🔸 Component 기반 함수형 라우팅은 DispatcherHandler를 안 탄다?
RouterFunction과 HandlerFunction을 사용하는 함수형 라우팅 방식은 Spring이 아니라 Netty 레벨에서 직접 등록되는 구조이다. 이 경우 DispatcherHandler를 거치지 않기 때문에 불필요한 체인을 줄이고 응답 속도가 미세하게 더 빠르다.
하지만 다음과 같은 단점이 있다:
- @Valid, @ControllerAdvice 같은 자동화 기능을 사용할 수 없음
- 모든 로직을 명시적으로 작성해야 하므로 생산성이 떨어질 수 있음
🔸 HandlerMapping과 HandlerAdapter란?
이 둘은 DispatcherHandler 내부의 핵심 구성요소이다.
컴포넌트 | 설명 |
HandlerMapping | 요청 URL, HTTP Method 등을 기준으로 어떤 핸들러(메서드 또는 함수)를 실행할지 결정 |
HandlerAdapter | HandlerMapping이 찾은 핸들러를 실제 실행할 수 있도록 어댑터 역할 수행 |
즉, HandlerMapping이 “누가 처리할지”를 찾고, HandlerAdapter가 “어떻게 실행할지”를 담당한다.
🔸 전체 요청 처리 흐름 비교
📌 RestController 방식
요청 → DispatcherHandler
├─ HandlerMapping → 핸들러 탐색
├─ HandlerAdapter → 핸들러 실행
└─ HandlerResultHandler → 응답 변환
📌 Component 함수형 라우팅 방식
요청 → Netty 직접 연결된 RouterFunction → HandlerFunction 실행 → 응답
🔸 정리: DispatcherHandler를 타는 것 vs 안 타는 것
항목 | DispatcherHandler 사용하는 경우 (@RestController) | DispatcherHandler 생략하는 경우 (RouterFunction) |
구조 | 고수준 Spring 구조 사용 | 저수준 직접 등록 방식 |
성능 | 약간의 오버헤드 존재 | 더 경량, 빠름 |
기능 지원 | Validation, ExceptionAdvice 등 풍부 | 최소한의 기능만 지원 |
사용 난이도 | 익숙하고 생산성 높음 | 명시적으로 작성해야 해서 구조적 |
적합 용도 | 복잡한 API, 도메인 중심 서비스 | 단순 라우팅, 헬스체크, 내부 API 등 |
✅ 결론
WebFlux에서는 DispatcherHandler를 중심으로 모든 요청 흐름이 처리된다. 하지만 RouterFunction을 사용하면 이 DispatcherHandler를 우회하게 되고, 이에 따라 성능 및 기능 측면에서 뚜렷한 차이를 보인다.
복잡한 비즈니스 로직이 필요한 API는 @RestController, 간단하고 빠른 처리가 필요한 API는 RouterFunction으로 선택적으로 사용하는 것이 좋다.
'BackEnd > Spring WebFlux' 카테고리의 다른 글
[WebFlux_1] @RestController vs @Component (0) | 2025.06.17 |
---|---|
Kotlin + Spring WebFlux 테스트 구조 설계기 (0) | 2025.05.28 |
Spring WebFlux에서 MySQL을 사용하는 방법: JDBC vs R2DBC 완전 정리 (0) | 2025.04.28 |
부록 - Spring Boot MVC vs Spring WebFlux 비교 (0) | 2025.04.28 |
Spring WebFlux 심화 시리즈 (4) - WebClient를 활용한 대용량 데이터 처리 (0) | 2025.04.28 |