WebFlux as a central reactive server foundation

As we saw in Chapter 1Why Reactive Spring?, and Chapter 4, Project Reactor - the Foundation for Reactive Apps, the new era of application servers has brought new techniques for developers. From the beginning of Spring Framework's evolution in the field of web applications, the decision was made to integrate the Spring Web module with Java EE's Servlet API. The entire infrastructure of the Spring Framework is built around Servlet API and they are tightly coupled. For instance, the entirety of Spring Web MVC is based on the Front Controller pattern. That pattern is implemented in Spring Web MVC by the org.springframework.web.servlet.DispatcherServlet class, which indirectly extends the javax.servlet.http.HttpServlet class.

On the other hand, the Spring Framework does give us a better level of abstraction in the Spring Web module, which is a building block for many features, such as annotation-driven controllers. Even though this module partially separates common interfaces from their implementations, the initial design of Spring Web was also based on the synchronous interaction model, and hence blocks the IO. Nevertheless, such separation is a good foundation, so before moving on to looking at the reactive web, let's recap the design of the web module and try to understand what is going on here:

Diagram 6.1. The implementation of the web stack in the Spring WebMVC module

 

The following is a description of the preceding diagram:

  1. The incoming request is handled by the underlying Servlet Container. Here, the Servlet Container is responsible for transforming an incoming body into the servlet API's ServletRequest interface and preparing the output in the form of the ServletResponse interface.
  2. The stage of filtering ServletRequest through filters is combined in FilterChain.
  3. The next stage is the DispatcherServlet processing stage. Remember that DispatcherServlet extends the Servlet class. It also holds the list of HandlerMappings (4), HandlerAdapters (5), and ViewResolvers (which is not depicted in the schema). In the context of the current execution flow, the DispatcherServlet class is responsible for searching for a HandlerMapping instance and adapting it using a suitable HandlerAdapter. It then searches for a ViewResolver that can resolve View so that DispatcherServlet initiates the rendering of the result of HandlerMapping and the HandlerAdapter execution.
  4. After that, we have the HandlerMapping stage. DispatcherServlet (3) searches for all of the HandlerMapping beans in the Application Context. During the mapping's initialization process, all instances found during the scanning process are sorted by order. The order number is specified by the @Order annotation, or in a case when HandlerMapping implements Ordered interface. Because of this, the lookup for suitable HandlerMapping instances depends on the order that was set up previously. In the preceding diagram, there are a few common HandlerMapping instances depicted. The most familiar one is RequestMappingHandlerMapping, which enables an annotation-based programming model.
  5. Finally, we have the RequestMappingHandlerAdapter stage, which takes care of the proper binding of the incoming ServletRequest to the @Controller annotated object. RequestMappingHandlerAdapter also provides request validation, response conversion, and many other helpful things that make the Spring Web MVC framework useful in everyday web development.

As we might have noticed, the overall design relies on the underlying servlet container, which is responsible for handling all mapped servlets inside the container. DispatchServlet acts as an integration point between the flexible and highly configurable Spring Web infrastructure and the heavy and complicated Servlet API. A configurable abstraction of HandlerMapping helps to separate the final business logic, such as controllers and beans, from the Servlet API.

Spring MVC supports direct interaction with HttpServletRequest and HttpServletResponse, along with mapping, binding, and validation features. However, when using these classes, we have an additional direct dependency on the Servlet API. This might be considered bad practice, because it may complicate the migration process from Web MVC to WebFlux, or any other web extension for Spring. It is recommended to use org.springframework.http.RequestEntity and org.springframework.http.ResponseEntity instead. These classes isolate requests and response objects from the web-server implementation.

The Spring Web MVC approach has been a convenient programming model for years. It has proved to be a solid and stable skeleton for web application development. This is why, in 2003, the Spring Framework started on its path to being one of the most popular solutions for building web applications on top of the Servlet API. However, methodologies and techniques of the past do not fit well with the requirements of modern data-intensive systems.

Despite the fact that the Servlet API supports asynchronous, non-blocking communication (starting from version 3.1), the implementation of the Spring MVC module has a lot of gaps and does not allow non-blocking operations throughout the request life cycle. For instance, there is no out-of-the-box non-blocking HTTP client, so any external interaction will most likely cause a blocking IO call. As mentioned in Chapter 5Going Reactive with Spring Boot 2, the Web MVC abstraction does not support all of the features of the non-blocking Servlet API 3.1. Until it does, Spring Web MVC cannot be considered a framework for high-load projects. Another disadvantage of the web abstraction in the old Spring is that there was no flexibility for reusing Spring Web features or programming models for a non-servlet server such as Netty.

That is why the central challenge for the Spring Framework team over the last few years has been to build a new solution that allows the same annotation-based programming model and provides all the benefits of asynchronous non-blocking servers at the same time.

..................Content has been hidden....................

You can't read the all page of ebook, please click here login for view all page.
Reset
18.191.237.201