Cabbage Java study room covers core knowledge

What is Spring WebFlux

The following is an excerpt from the Spring Boot official website:

Before we learn about Spring WebFlux, let’s compare what Spring MVC is. It is more beneficial for us to understand WebFlux. The definition of Spring MVC on the right side of the figure is as follows:

Spring MVC is built on the Servlet API and uses a synchronous blocking I/O architecture whth a one-request-per-thread model.

Spring MVC builds on the Servlet API and uses a synchronous blocking I/O model. What is a synchronous blocking I/O model? That is, each request is processed by one thread.

After understanding Spring MVC, let’s talk about Spring WebFlux:

On the left, the official definition is as follows:

Spring WebFlux is a non-blocking web framework built from the ground up to take advantage of multi-core, next-generation processors and handle massive numbers of concurrent connections.

Spring WebFlux is an asynchronous, non-blocking Web framework that takes advantage of the hardware resources of a multi-core CPU to handle a large number of concurrent requests.

2. WebFlux benefits & Performance improvement?

WebFlux uses Reactive Programming internally. Based on the Reactor library, it is asynchronous and event-driven, which enables us to improve the throughput and scalability of the system without expanding hardware resources.

Looking at this, would you expect WebFlux to make applications run faster? Quantifying, for example, since I use WebFlux, does the response time for a request on an interface decrease?

Sorry, the answer is no! Here’s the official quote:

Reactive and non-blocking generally do not make applications run faster.

WebFlux does not reduce the response time of the interface, it only improves throughput and scalability.

3. Application scenarios of WebFlux

As mentioned above, Spring WebFlux is an asynchronous, non-blocking Web framework, so it is particularly suitable for IO intensive services such as microservice gateways.

PS: IO intensive includes: disk IO intensive, network IO intensive, microservice gateway belongs to network IO intensive, using asynchronous non-blocking programming model, can significantly improve the gateway to downstream service forwarding throughput.

WebFlux or Spring MVC?

First you need to be clear: WebFlux is not an alternative to Spring MVC! Although WebFlux can also be run on Servlet containers (Servlet 3.1+ or above), WebFlux is primarily applied in an asynchronous non-blocking programming model, whereas Spring MVC is synchronous blocking. If you are currently heavily using asynchronous solutions in the Spring MVC framework, then WebFlux is what you want, otherwise Spring MVC is your first choice.

In the microservices architecture, Spring MVC and WebFlux can be mixed. As mentioned, for IO intensive services such as gateways, we can use WebFlux.

WebFlux or Spring MVC? This is not a problem!

We can’t just play it for the sake of playing it for the sake of playing it for the sake of playing it for the sake of playing it for the sake of playing it for the sake of playing it for the sake of playing it for the sake of playing it for the sake of playing it for the sake of playing it for the sake of playing it for the sake of playing it for the sake of playing it.

In short, select the most appropriate technology for the right scene.

5. Similarities and differences

From the figure above, you can see at a glance the similarities and differences between Spring MVC and Spring WebFlux:

Similarities:

  • Spring MVC annotations can be used, such as@Controller, allowing us to freely convert between the two Web frameworks;
  • Tomcat, Jetty, and Undertow Servlet containers (Servlet 3.1+) are available;

Note:

  • Because Spring MVC is used synchronous blocking, it is more convenient for developers to write functional code, Debug testing, etc. In general, if Spring MVC can meet the scenario, try not to use WebFlux;
  • By default, WebFlux uses Netty as the server.
  • WebFlux does not support MySql.

How does WebFlux distribute requests

For those of you who have used Spring MVC, you should know that Spring MVC’s front-end controller is DispatcherServlet, and WebFlux is DispatcherHandler, which implements the WebHandler interface:

public interface WebHandler {
    Mono<Void> handle(ServerWebExchange var1);
}
Copy the code

Take a look at the Handle method in the DispatcherHandler class that handles requests:

    public Mono<Void> handle(ServerWebExchange exchange) {
        return this.handlerMappings == null ? this.createNotFoundError() : Flux.fromIterable(this.handlerMappings).concatMap((mapping) -> {
            return mapping.getHandler(exchange);
        }).next().switchIfEmpty(this.createNotFoundError()).flatMap((handler) -> {
            return this.invokeHandler(exchange, handler);
        }).flatMap((result) -> {
            return this.handleResult(exchange, result);
        });
    }
Copy the code
  • ServerWebExchange object to place each HTTP request response information, including parameters;
  • ② : Check whether the entire interface mapping set is empty. If the “mappings” set is empty, a “Not Found” error is created.
  • ③ : Obtain the corresponding handlerMapping according to the specific request address;
  • ④ : Call the specific business method, that is, we define the interface method;
  • ⑤ : Process the returned results;

Quick Start

7.1 Adding a WebFlux Dependency

Create a new Spring Boot project and add webflux dependencies to the pom.xml file:

<dependency>
    <groupId>org.springframework.boot</groupId>
    <artifactId>spring-boot-starter-webflux</artifactId>
</dependency>
Copy the code

7.2 Defining Interfaces

Create a new Controller package to house the external interface classes and create a new WebFluxController class to define two interfaces:

@RestController public class WebFluxController { @GetMapping("/hello") public String hello() { return "Hello, WebFlux !" ; } @GetMapping("/user") public Mono<UserDO> getUser() { UserDO user = new UserDO(); User. Elegantly-named setName (" cabbage "); User.setdesc (" Cabbages Java Study Room "); return Mono.just(user); }}Copy the code
@data public class UserDO {/** * name */ private String name; / / private String desc; }Copy the code

In the above controller class, we use Spring MVC annotations, which define two interfaces:

  • A GET request/helloInterface, returns Hello, WebFlux! A string.
  • Defines another GET request/userMethod that returns a JSON-formatted User object.

Notice here that the User object is wrapped around the Mono object, so you might ask, why not just return it?

In WebFlux, Mono is written in a non-blocking way. Only in this way can you take advantage of WebFlux’s non-blocking + asynchronous features.

In WebFlux, in addition to Mono, there is also a Flux, the difference is:

  • Mono: Returns 0 or 1 elements, a single object.
  • Flux: returns N elements, that is, List List objects.

7.3 Testing Interfaces

Start the project and view the console output:

When the console output includes the Netty started on port(s): 8080 statement, the default Netty service has been started.

The /hello interface is called first:

GET http://localhost:8080/hello
Accept: application/json
Copy the code
GET http://localhost:8080/hello HTTP / 1.1 200 OK the content-type: application/json; charset=UTF-8 Content-Length: 16 Hello, WebFlux ! Response code: 200 (OK); Time: 681ms; Content length: 16 bytesCopy the code

Let’s test the /user interface again:

GET http://localhost:8080/user
Accept: application/json
Copy the code
GET http://localhost:8080/user HTTP / 1.1 200 OK the content-type: application/json Content - Length: 46 {" name ": } Response code: 200 (OK); Time: 148ms; Content length: 32 bytesCopy the code