ABOUT ME

-

Today
-
Yesterday
-
Total
-
  • Spring Webflux - DispatcherHandler
    spring 2019. 7. 18. 12:50

    개요


    스프링 webflux의 request 처리는 DispatcherHandler를 거쳐 적절한 handler에 요청 처리를 맡기는 형태이다. 스프링 MVC에서 DispatcherServlet의 역할을 DispatcherHandler가 한다고 생각하면 된다. WebHttpHandlerBuilder가 HttpHandler들을 체이닝하는데, DispatcherHandler도 함께 체이닝된다.

     

    전반적인 request 처리 과정은 아래와 같다.

     

    웹서버(netty, jetty 등)에서 handle → ServerManager.handle() → 체인된 HttpHandler들 → DispatcherHandler.handle() 의 과정으로 HttpHandler에서 리퀘스트가 처리된다.

     

    DispatcherHandler에 전달된 exchange(request와 response 객체를 포함)가 HandlerMapping → HandlerAdapter → HandlerResultHanlder 를 거쳐 처리되어 response를 반환한다.

     

    made by hychul

    Special Bean Types


    개요에서 언급한 바와 같이, DispatcherHandler는 request를 특별한 bean들에게 위임하게 되는데, 각 설명은 아래와 같다.

     

    Bean type 설명
    HandlerMapping

    request를 핸들러에 맵핑해준다. 맵핑 방식은 구현 방식에 달려있다.

    1.  RequestMappingHandlerMapping - @RequestMapping 어노테이션 메소드 맵핑

    2. RouterFunctionMapping - functional endpoint 방식의 메소드 맵핑

    3. SimpleUrlHandlerMapping - 명확한 URI path pattern으로 등록된 메소드 맵핑

    HandlerAdapter DispatcherHandler가 맵핑된 핸들러가 어떻게 실제로 호출될 수 있을지를  고민하지 않도록, HandlerAdapter가 디테일을 처리해준다.
    HandlerResultHandler handler의 result를 처리하고, respone를 최종적으로 만들어준다.

     

    Processing


    DispatcherHandler 요청 프로세스는 다음과 같다.

     

    - 각 HandlerMapping이 핸들러를 매칭하도록 요청 받고, 첫 번째로 매칭이 된 것이 사용된다.

    - 적절한 HandlerAdapter를 통해 핸들러가 실행이 되고, return value는 HandlerResult로 랩핑된다.

    - HandlerResult는 적절한 HandlerResultHandler에 넘어가고, response를 바로 쓰거나 view를 렌더링하면서 처리가 완료된다.

     

     

    Result Handling


    HandlerResultHandler의 구현체들 다음과 같은 종류가 있다.

     

    Result Handler Type Return Values Default Order
    ResponseEntityResultHandler ResponseEntity, 전형적으로 @Controller 인스턴스들로부터의 result가 이에 해당한다. 0
    ServerResponseResultHandler ServerResponse, 전형적으로 functional endpoints로부터의 result가 이에 해당한다. 0
    ResponseBodyResultHandler @ResponseBody 메소드들이나 @RestController 클래스(@Controller + @ResponseBody) 로부터의 리턴 값들을 처리한다. 100
    ViewResolutionResultHandler CharSequence, View, Model, Map, Rendering(Srping MVC의 ModelAndView)를 처리하며, 기타 Object들은 model attribute로 간주된다. Integer.MAX_VALUE

     

    Exceptions


    HandlerAdapter로부터 리턴된 HandlerResult는 다음과 같은 경우에 error function을 호출한다.

     

    - 핸들러 처리가 실패한 경우

    - HandlerReusltHandler가 핸들러 리턴 값 처리를 실패한 경우

     

    스프링 MVC에서처럼, @Controller 내에 @ExceptionHandler 어노테이션을 붙인 메소드들로 에러를 처리할 수 있다. 하지만 스프링 MVC에서는 @ControllerAdvice로 핸들러 맵핑 이전에 발생된 에러들도 처리가 가능했던 것과 달리 스프링 webflux에서는 핸들러가 맵핑이 된 이후에 발생한 에러만 처리가 가능하다.

     

    @Controller 
    public class DemoController { 
    	... 
    	@ExceptionHandler 
    	public ResponseEntity<String> handle(IOException ex) { // ... } 
    }
    

     

    View Resolution


    앞의 Result Handling 부분에서 잠시 언급한 ViewResoultionResultHandler가 view를 렌더링할 수 있도록 처리해주는 역할을 한다. ViewResolutionHandler로 들어오는 HandlerReuslt는 핸들러의 return 값과 리퀘스트 처리를 하면서 attributes가 추가된 model 객체를 들고 있다. 핸들러의 return 값은 그 타입에 따라 다음 중 하나로 처리된다.

     

    - String, CharSequence: view name으로 간주하고 ViewResovler를 통해 해당 이름의 파일을 찾아서 View객체로 만든다.

    - void: request path에 따른 default view 이름을 골라서 View객체로 만든다. 이 경우는 void 타입의 리턴 뿐만 아니라 view 이름이 지정되지 않았을 때(ex. model attribute 리턴, Mono<Void>)에도 해당된다.

    - Rendering: view resolution과 관련된 API를 제공한다. 관련 문서 참고

    - Model, Map: 요청의 model에 이 attributes를 추가로 더한다.

    - 기타: 기타 리턴 값은 model attribtue에 추가로 더한다.

     

    model에는 비동기, reactive 타입들이 있을 수 있다. 이들이 렌더링되기 전에 앞서, AbstractView가 이들의 내용물을 꺼내서 model에 업데이트해준다. Flux처럼 여러 값이 있는 타입이라면, 이들을 꺼내서 List로 만들고 model에 업데이트해준다.

     

     

    참고


    https://docs.spring.io/spring/docs/current/spring-framework-reference/web-reactive.html#webflux-dispatcher-handler

    'spring' 카테고리의 다른 글

    Spring Webflux - CORS  (0) 2019.07.31
    Spring Webflux - Functional Endpoints  (0) 2019.07.25
    Spring WebClient  (0) 2019.07.10
    Spring Webflux + Reactor  (0) 2019.05.13
    Spring AMQP  (0) 2019.05.13

    댓글

Designed by Tistory.