Spring Web Reactive | 1. Spring WebFlux | 1.3. DispatcherHandler

Web MVC

Spring WebFlux은 Spring MVC와 마찬가지로 프런트 컨트롤러 패턴을 중심으로 설계되어 있으며, 중앙의 WebHandlerDispatcherHandler가 요청 처리의 공유 알고리즘을 제공하고, 실제 작업은 구성 가능한 위임(delegate) 컨포넌트에 의해 실행된다 . 이 모델은 유연하고 다양한 워크 플로우를 지원한다.

DispatcherHandler는 Spring 설정에서 필요한 위임 컨포넌트를 검색한다. 그러고, Spring Bean 자체되도록 설계되어 실행되는 컨텍스트에 액세스하기 위해 ApplicationContextAware를 구현한다. DispatcherHandlerwebHandler이라는 Bean 이름으로 선언되는 경우 WebHandler API에 따라 요청 처리 체인을 모와서 WebHttpHandlerBuilder에 의해 검색된다.

WebFlux 응용 프로그램의 Spring 설정은 일반적으로 다음이 포함된다.

다음의 예제에서 알 수 있듯이, 처리는 체인을 구축하기 위해 WebHttpHandlerBuilder에 주어진다.

Java

ApplicationContext context = ...
HttpHandler handler = WebHttpHandlerBuilder.applicationContext(context).build();

Kotlin

val context: ApplicationContext = ...
val handler = WebHttpHandlerBuilder.applicationContext(context).build()

결과 HttpHandler서버 어댑터에서 함께 사용할 준비가 되어 있다.

1.3.1. 특별한 Bean 유형(Special Bean Types)

Web MVC

DispatcherHandler는 요청을 처리하고 적절한 응답을 렌더링하는데 특별한 Bean에 위임한다. “특별한 Bean"이란, WebFlux 프레임워크의 요소를 구현하는 Spring 관리 Object 인스턴스를 의미한다. 기본적으로 내장(built-in)되어 있지만, 속성을 정의하거나 확장하거나 교체 할 수 있다.

다음 표는 DispatcherHandler 의해 검지된 특별한 Bean을 보여준다. 낮은 레벨에서 감지된 그밖에 Bean도 일부 있다는 점에 유의해라(Web 핸들러 API의 특별한 Bean 유형 참조).

Bean 유형 설명
HandlerMapping 요청을 핸들러에 매핑한다. 매핑은 몇 가지 조건을 기반으로 하며, 그 자세한 내용은 HandlerMapping 구현에 따라 달라진다. 주석이 선언된 컨트롤러, 간단한 URL 패턴 매핑 등. 주요 HandlerMapping 구현은 @RequestMapping 어노테이션이 선언된 메서드의 RequestMappingHandlerMapping, 함수 엔드 포인트 루트의 RouterFunctionMapping 및 URI 경로 패턴과 WebHandler 인스턴스의 명시적인 등록 SimpleUrlHandlerMapping이다.
HandlerAdapter 핸들러가 실제로 호출되는 방법에 관계없이, DispatcherHandler가 요청에 매핑 된 핸들러를 호출하는데 도움이 된다. 예: 어노테이션이 선언된 컨트롤러를 호출하려면 어노테이션에 대한 리졸버가 있어야 하는데, HandlerAdapter의 주요 목적은 그러 구체적인 부분까지는 DispatcherHandler에서 관여할 필요 없이 처리를 분리하는 것이다.
HandlerResultHandler 핸들러 호출의 결과를 처리하고 응답을 확인한다. 결과 핸들링를 참조해라.

1.3.2. WebFlux 구성

Web MVC

응용 프로그램은 요청을 처리하는 데 필요한 인프라 Bean(Web 핸들러 APIDispatcherHandler에 목록화되어 있다)를 선언 할 수 있다. 그러나 대부분의 경우 WebFlux 구성이 최적의 출밤점이다. 필요한 Bean을 선언하고 그것을 정의하기 위한 높은 레벨의 구성 콜백 API를 제공한다.

Spring Boot는 WebFlux 구성에 따라 Spring WebFlux를 구성하고, 더욱 편리한 옵션을 제공한다.

1.3.3. 처리

Web MVC

DispatcherHandler는 요청을 다음과 같이 처리한다.

  • HandlerMapping 일치하는 핸드러를 찾을 수 있도록 도와주고, 처음 메칭된 핸드러가 사용된다.
  • 핸들러가 찾으면 적절한 HandlerAdapter를 통해 실행되며, 실행에서 반환 값을 HandlerResult로 전달한다.
  • HandlerResult는 적절한 HandlerResultHandler에 전달된 응답을 직접 만들거나, 뷰를 사용하여 렌더링 처리를 완료한다.

1.3.4. 결과 처리(Result Handling)

HandlerAdapter를 통해 핸들러의 호출의 반환 값은 추가 컨텍스트와 함께 HandlerResult로 싸여 그 지원을 요구하는 첫번째 HandlerResultHandler에 전달된다. 다음 표는 사용 가능한 HandlerResultHandler 구현을 보여준다. 이들은 모두 WebFlux 구성에 선언되어 있다.

결과 핸들러 유형 반환 값 기본 순서
ResponseEntityResultHandler ResponseEntity, 일반적으로 @Controller 인스턴스에서 사용. 0
ServerResponseResultHandler ServerResponse 일반적으로 함수 엔드 포인트에서 사용. 0
ResponseBodyResultHandler @ResponseBody 메소드 또는 @RestController 클래스에서 반환 값을 처리한다. 100
ViewResolutionResultHandler CharSequence, View, Model, Map, Rendering이나 다른 Object는 모델 속성으로 처리된다. 뷰 리졸버를 참조해라. Integer.MAX_VALUE

1.3.5. 예외(Exceptions)

Web MVC

HandlerAdapter에서 반환된 HandlerResult는 핸들러 고유의 메커니즘을 기반으로 에러 핸들링 함수를 제공한다. 이 에러 핸들링 함수는 다음의 경우에 호출된다:

  • 핸들러 (예를 들어, @Controller) 호출 실패
  • HandlerResultHandler를 통한 핸들러 반환 처리실패

에러 함수는 핸들러에서 반환되는 리액티브 유형의 데이터 항목을 생성하기 전에 에러 신호가 발생하면, 응답(예를 들어, 에러 상태:status)를 변경할 수 있다.

그래서 @Controller 클래스의 @ExceptionHandler 메서드가 지원된다. 반면 Spring MVC에서의 동일한 지원은 HandlerExceptionResolver을 기반으로 한다. 이는 그리 중요하지 않다. 다만, WebFlux는 @ControllerAdvice을 사용하여 핸들러가 선택되기 전에 발생하는 예외를 처리 할 수 없음에 주의해라.

“어노테이션이 선언된 컨트롤러"섹션의 예외 관리 또는 WebHandler API 섹션의 예외를 참조해라.

1.3.6. 뷰 리솔루션(View Resolution)

Web MVC

뷰 리솔루션(View Resolution)를 사용하면 특정 뷰 기술에 얽매이지 않고, HTML 템플릿과 모델을 사용하여 브라우저에 렌더링 할 수 있다. Spring WebFlux는 ViewResolver 인스턴스를 사용하여 문자열(논리적 뷰 이름을 나타내는)를 View 인스턴스에 매핑하는 전용 HandlerResultHandler를 통해 뷰 리솔루션이 지원되고 있다. 다음은 View를 사용하여 응답을 렌더링한다.

핸들링(Handling)

Web MVC

ViewResolutionResultHandler에 전달되는 HandlerResult는 핸들러로부터의 반환 값과 요청 처리 중에 추가 된 속성을 포함하는 모델이 포함되어 있다. 반환 값은 다음 중 하나로 처리된다.

  • String, CharSequence : 구성된 ViewResolver 구현의 목록을 통해 View에서 만들어지는 논리적 뷰 이름.
  • void : 요청 경로에 따라 앞뒤에 슬래시를 제외한 디폴트 뷰 이름을 선택하고, View에서 해결한다. 뷰 이름이 지정되지 않은 경우(모델 속성이 반환된 경우 등) 또는 비동기 반환 값 (예를 들어, 빈어 있는 Mono가 완료된 경우)에서도 동일하게 처리한다.
  • Rendering : 뷰 리솔루션 시나리오 API. IDE 자동 완성의 옵션을 찾아보자.
  • Model, Map : 요청의 모델에 추가된 추가 모델 속성.
  • 그 외 : 다른 반환 값(BeanUtils#isSimpleProperty에 의해 결정되는 단순한 유형 제외)는 모델에 추가되는 모델 속성으로 처리된다. 핸들러 메소드 @ModelAttribute 어노테이션이 존재하지 않는 속성 이름은 Conventions을 사용하여 클래스 이름으로부터 얻어진다.

모델은 비동기 리액티브 타입을 포함 할 수 있다(예를 들어, Reactor 또는 RxJava에서). AbstractView는 이러한 모델 특성을 렌더링 전에 구체적인 값으로 값으로 리졸빙하고 그 모델을 업데이트한다. 단일 값의 리액티브 타입은 단일 값 또는 값 없음(비어있는 경우)로 확인된 여러 값의 리액티브 유형(예를 들어, Flux<T>)는 수집 된 List<T>에 리졸빙된다.

뷰 리졸버 조치를 구성하려면 ViewResolutionResultHandler Bean을 Spring 설정에 추가 하면 된다. WebFlux 구성은 뷰 리졸버 우퍼 전용 구성 API를 제공한다.

Spring WebFlux와 통합 된 뷰 기술에 대한 자세한 내용은 뷰 기술을 참조해라.

리디렉션(Redirecting)

Web MVC

뷰 이름의 특별한 redirect: 접두사(prefix)를 붙이면 리디렉션 할 수 있다. UrlBasedViewResolver (및 서브 클래스)는이를 리디렉션이 필요한 명령으로 인식한다. 뷰 이름의 나머지는 리디렉션 URL이다.

최종 효과는 컨트롤러가 RedirectView 또는 Rendering.redirectTo("abc").build()를 반환한 경우와 동일하지만 컨트롤러 자체가 논리적 뷰 이름의 관점에서 작동 할 수 있게 되어 있다. redirect:/some/resource와 같은 뷰 이름은 현재 응용 프로그램에 관련이 있지만, redirect:https://example.com/arbitrary/path 와 같이 하면 절대 경로 URL로 리디렉션된다.

콘텐츠 협상(Content Negotiation)

Web MVC

ViewResolutionResultHandler 콘텐츠 협상을 지원하고 있다. 요청 미디어 유형과 선택한 각 View에서 지원되는 미디어 유형을 비교한다. 요청한 미디어 타입을 지원하는 최초의 View가 사용된다.

JSON 또는 XML 등의 미디어 타입을 지원하기 위해, Spring WebFlux는 HttpMessageWriterView을 제공한다. 이는 HttpMessageWriter을 통해 렌더링하는 특별한 View이다. 일반적으로 이들은 WebFlux 설정을 통해 기본 뷰로 설정한다. 요청한 미디어 타입에 일치하는 경우 기본 뷰가 항상 선택되어 사용된다.




최종 수정 : 2021-04-12