BackEnd/Spring WebFlux

[WebFlux_2] @RestController vs @Component

Raconer 2025. 6. 20. 15:41
728x90

✅ Spring WebFlux의 핵심 구조: DispatcherHandler와 그 내부 구조

앞에서 @RestController@Component 방식의 차이를 다뤘다면, 이번에는 이 둘이 내부적으로 어떤 구조에서 동작하며, 왜 그 차이가 발생하는지를 정리해본다.


🔸 DispatcherHandler란?

DispatcherHandler는 Spring WebFlux의 중앙 진입점이다. Spring MVC에서의 DispatcherServlet과 역할이 동일하며, HTTP 요청을 받아 핸들러를 찾고 실행한 뒤 결과를 반환하는 흐름을 제어한다.

 

WebFlux는 논블로킹 환경에서 동작하기 때문에 DispatcherHandler도 내부적으로 MonoFlux를 사용해 모든 처리를 리액티브하게 실행한다.


🔸 RestController는 왜 DispatcherHandler를 타는가?

@RestController 기반의 API는 Spring이 자동 구성한 HandlerMappingHandlerAdapter에 등록된 정보에 따라 동작한다. 따라서 모든 요청은 반드시 DispatcherHandler를 경유하게 된다.

 

이 덕분에 다음과 같은 고수준 기능들을 사용할 수 있다:

  • @Valid 등의 요청 검증
  • @ControllerAdvice를 통한 전역 예외 처리
  • @ModelAttribute, @RequestParam 자동 바인딩

🔸 Component 기반 함수형 라우팅은 DispatcherHandler를 안 탄다?

RouterFunctionHandlerFunction을 사용하는 함수형 라우팅 방식은 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으로 선택적으로 사용하는 것이 좋다.
728x90