Introducing Spring MVC Async and Spring WebFlux
I, Arslan Mirbzergi,in this article, I will review Async [email protected] in Spring MVC and then I will meet you with Spring WebFlux. The goal is to better understand the differences between the two frameworks.
Spring MVC’s @Async annotation and Spring WebFlux will be covered in this tutorial. We need to know the differences between the two to make the right decisions going forward.
Actualization of the Plan
Here, we’ll pick a scenario to demonstrate how each of these APIs can be used to build a simple web application. Moreover, thread management and blocking vs. non-blocking I/O are particularly intriguing topics for us to explore further.
Think of a web app that just returns a string from one endpoint. The key point is that 200ms will delay the request as it passes through a Filter and then by 500ms as it is calculated and returned by the Controller.
Next, we’ll use Apache ab to simulate a load on both endpoints and use JConsole to track our app’s behavior.
It’s worth noting that the purpose of this article is not to compare the two APIs but rather to run a small load test to see how each one handles thread management.
Spring MVC Async
A new annotation, @Async, debuted in Spring 3.0. With @Async, heavy-load jobs can be handled by a separate thread. In addition, if the caller is eager to know the outcome, they can stay on the line and wait. It’s for this reason that the return type can only be Future or CompletableFuture and not void.
As well as this, Spring 3.0 introduced Servlet 3.0, which brings asynchronous functionality to the web layer in the form of the org. spring framework.web.context.request. Async package. As a result, classes annotated as @Controller or @RestController can now use @Async in Spring 3.2 and later.
An initial request is sent to the DispatcherServlet instance, which processes it through all matching filters.
The servlet then handles the request’s async dispatching. It starts the request by calling AsyncWebRequest#startAsync, then passes control of handling the request to an instance of WebSyncManager and exits. The filter chain is also retraced back to the beginning at the root.
WebAsyncManager submits the request processing job to its associated ExecutorService. It notifies DispatcherServlet to send back the response to the client when the result is ready.
Implementation of Spring Async
Let’s begin implementing AsyncVs WebFluxApp by writing our application class. For our Spring Boot application, the magic happens here with @EnableAsync:
Then we have AsyncFilter, which implements javax.servlet.Filter. Don’t forget to simulate the delay in the doFilter way:
Filter. In the doFilter method, be sure to include a delay simulation:
Finally, we create an AsyncController with a “/async result” endpoint, as shown below.
This method is executed on the application’s default ExecutorService and a separate thread because of the @Async above getResultAsync. Our method can, however, be given its own ExecutorService.
Now is the appropriate time to put your skills to the test! Let’s start the application and set up Apache ab or some other appropriate tool to simulate the load. The “async result” endpoint allows us to send multiple requests at once. If you want to keep an eye on the progress of your Java application, you can use JConsole.
WebFlux, a new feature in Spring 5.0, provides non-blocking support for the reactive web. Based on the reactor API, WebFlux makes use of the reactive stream yet again.
Reactive backpressure is supported in Spring WebFlux, as is Servlet 3.1+’s non-blocking I/O. The result is that Netty or Undertow or Jetty or Tomcat or any Servlet 3.1+ server can run it.
Spring WebFlux will work as long as the server supports non-blocking I/O and reactive backpressure, even if the server’s thread management and concurrency control model differ.
Spring WebFlux gives us the ability to declaratively decompose the logic using Mono, Flux, and their extensive set of operators. Aside from the @Controller annotated ones, we can also use these in Spring MVC now that they’re functional endpoints.
Implementation of Spring WebFlux
We follow the same path as async when it comes to WebFlux implementations. We will begin by constructing the AsyncVs WebFluxApp.
After that, let’s create our own WebFluxFilter that uses WebFilter as a base. We’ll intentionally delay the request before sending it through the rest of the filter chain.
Our WebFluxController is finally here. It exposes a “/flux result” endpoint and responds with a MonoString>:
Our async sample application will serve as a good comparison for this test. For an example, think about the following circumstances:
What Is the Distinction?
Spring Async is compatible with Servlet 3.0, but Spring WebFlux is compatible with Servlet 3.1 and beyond. There are several differences as a result of this:
When communicating with the client, the Spring Async I/O model is blocking. Customers with slow internet connections may experience issues. Spring WebFlux, on the other hand, offers a non-blocking I/O model.
Spring Async blocks on reading the request body or request parts, whereas Spring WebFlux does not.
Spring Async uses synchronous communication for Filters and Servlets, whereas Spring WebFlux uses asynchronous communication.
Unlike Spring Async, Spring WebFlux is compatible with a wider range of Web/Application servers, such as Netty and Undertow.
We have more control over how we are able to react to fast producers with Spring WebFlux because it supports reactive backpressure, which Spring MVC Async and Spring MVC don’t.
Thanks to Reactor API, Spring Flux has also made a noticeable shift toward functional coding style and declarative API decomposition.
Is it safe to say that all of these things point us toward using Spring WebFlux? Spring Async or even Spring MVC may be the best choice for many projects, depending on the desired load scalability or system availability.
The asynchronous Spring Async implementation outperforms the synchronous Spring MVC implementation when it comes to scaling. Because of its reactive nature, Spring WebFlux gives us more flexibility and higher uptime.
Here we learned more about Spring Async, and then we did a basic load test to see how they compared to Spring WebFlux.
All of the code for the Async and WebFlux examples can be found on GitHub, as per usual.
And in the end,
The question is, does all of this lead us to use Spring WebFlux? Spring Async or even Spring MVC may be the right solution for many existing projects, depending on the appropriate scalability load or availability of the system. In the case of Scalability, using Spring Async gives us better results than running synchronous Spring MVC, and Spring WebFlux provides higher Elasticity and Availability due to its Reactive nature.