Spring Web vs Spring Webflux

Burak KOCAK
4 min readMar 8, 2023

--

Spring Web vs Spring Webflux

Spring Web and Spring Webflux are both frameworks in the Spring ecosystem that are used for building web applications, but they have some key differences.

Spring Web is a traditional web framework that is built on top of the Servlet API. It is designed to handle blocking I/O, where a thread is blocked until a response is received from a database or another service. Spring Web is well-suited for traditional web applications that require synchronous communication.

Spring Webflux, on the other hand, is a reactive web framework that is built on top of Reactive Streams. It is designed to handle non-blocking I/O, where a thread is not blocked while waiting for a response from a database or another service. Instead, the application can continue to process other requests while waiting for the response. Spring Webflux is well-suited for applications that require high concurrency, such as streaming applications or real-time data processing.

In summary, if you are building a traditional web application with synchronous communication, then Spring Web may be a good choice for you. If you are building a highly-concurrent application with non-blocking I/O, then Spring Webflux may be a better choice.

Let’s consider an example of building a web application that retrieves weather data from a third-party API and displays it to users.

In a traditional Spring Web application, the controller would use blocking I/O to retrieve the weather data from the API, and the user would have to wait until the data is retrieved before seeing the weather information. This is suitable for small-scale applications with low-concurrency needs.

On the other hand, in a Spring Webflux application, the controller would use non-blocking I/O to retrieve the weather data from the API, and the user can see the page load while the data is being retrieved in the background. This is suitable for large-scale applications with high-concurrency needs.

Here’s how the code might look for both examples:

Spring Web example:

@RestController
public class WeatherController {

@Autowired
private WeatherService weatherService;

@GetMapping("/weather")
public String getWeather() {
WeatherData weatherData = weatherService.getWeatherData();
return "The temperature in " + weatherData.getCity() + " is " + weatherData.getTemperature() + " degrees Celsius.";
}
}

@Service
public class WeatherService {

@Autowired
private RestTemplate restTemplate;

public WeatherData getWeatherData() {
ResponseEntity<WeatherData> response = restTemplate.getForEntity("https://api.weather.com/weatherdata", WeatherData.class);
return response.getBody();
}
}

Spring Webflux example:

@RestController
public class WeatherController {

@Autowired
private WeatherService weatherService;

@GetMapping("/weather")
public Mono<String> getWeather() {
return weatherService.getWeatherData().map(weatherData -> "The temperature in " + weatherData.getCity() + " is " + weatherData.getTemperature() + " degrees Celsius.");
}
}

@Service
public class WeatherService {

@Autowired
private WebClient webClient;

public Mono<WeatherData> getWeatherData() {
return webClient.get().uri("https://api.weather.com/weatherdata").retrieve().bodyToMono(WeatherData.class);
}
}

As you can see, the Spring Webflux example uses reactive programming concepts, such as Mono and WebClient, to handle non-blocking I/O and concurrency. While the Spring Web example uses traditional blocking I/O concepts, such as RestTemplate and ResponseEntity.

If both Spring Web and Spring Webflux are running on the same system resources and 300 incoming requests are made at the same time, Spring Webflux would perform better due to its non-blocking I/O approach.

In Spring Web, each incoming request will be processed synchronously, which means that the thread handling the request will be blocked until the response is received. With 300 incoming requests, this would result in 300 threads being blocked, which can lead to high CPU and memory usage.

In contrast, Spring Webflux would be able to handle 300 incoming requests concurrently using a single thread, since it uses non-blocking I/O. The thread handling the request would not be blocked while waiting for the response, but would instead be able to handle other requests. This results in lower CPU and memory usage compared to Spring Web.

In summary, if you need to handle a high-concurrency workload, Spring Webflux would be a better choice due to its ability to handle non-blocking I/O and its efficiency in using system resources.

Here are the Maven dependencies and configuration files for Spring Web and Spring Webflux.

Maven dependencies for Spring Web:

<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-web</artifactId>
<version>2.6.2</version>
</dependency>

<dependency>
<groupId>org.postgresql</groupId>
<artifactId>postgresql</artifactId>
<version>42.3.1</version>
</dependency>

This dependency includes the following libraries:

  • Spring Web
  • Spring Web MVC
  • Spring Boot auto-configuration
  • Spring Boot Actuator (for monitoring and managing the application)

application.yml

server:
port: 8080
spring:
datasource:
url: jdbc:postgresql://localhost:5432/mydb
username: myusername
password: mypassword
driver-class-name: org.postgresql.Driver
jpa:
hibernate:
ddl-auto: update

Maven dependencies for Spring Webflux:

<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-webflux</artifactId>
<version>2.6.2</version>
</dependency>

<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-data-mongodb-reactive</artifactId>
<version>2.6.2</version>
</dependency>

application.yml

server:
port: 8080
spring:
data:
mongodb:
host: localhost
port: 27017
database: mydb
username: myusername
password: mypassword

--

--