Spring WebFlux is a part of the Spring Framework that supports reactive programming and offers an alternative to Spring MVC for building asynchronous, non-blocking web applications. Reactor is the reactive library behind WebFlux, providing tools and abstractions for working with asynchronous streams. Understanding the threading model of Spring WebFlux and Reactor is crucial for efficiently building scalable applications that handle a large number of concurrent users without blocking threads.
Main Concept
In traditional web frameworks like Spring MVC, each request is handled by a dedicated thread from a thread pool. This model can lead to performance issues as the number of concurrent users increases, potentially exhausting the thread pool and causing delays or failures.
Spring WebFlux, on the other hand, is built on Reactor and follows a different threading model. WebFlux leverages a small number of threads, often as few as one per CPU core, to handle many concurrent requests due to the non-blocking nature of reactive programming.
Reactor's Scheduler
Reactor provides a set of Schedulers that control how tasks are executed on different threads. The commonly used Schedulers in WebFlux are:
- Schedulers.parallel(): Executes tasks on a parallel thread pool, suitable for CPU-bound operations.
- Schedulers.elastic(): Creates new threads as needed and reuses idle ones, suitable for blocking operations.
- Schedulers.single(): Executes tasks on a single reusable thread.
- Schedulers.immediate(): Executes tasks on the caller's thread.
Event Loop Model
WebFlux uses an event loop model similar to Node.js, where a small number of threads handle I/O events. The Netty or Undertow server, commonly used with WebFlux, runs the event loop that processes I/O events and delegates request processing to the reactive pipeline.
Non-blocking I/O
In WebFlux, I/O operations such as database calls or HTTP requests are non-blocking. Instead of waiting for I/O operations to complete, the thread can continue processing other requests, improving overall throughput.
Prerequisites:
- Familiarity with reactive programming principles such as the Observer pattern, backpressure, and reactive streams.
- Basic knowledge of creating and running Spring Boot applications.
- Basic knowledge of threads and concurrency.
Implementing the Reactive API with Spring WebFlux
Step 1: Create the Spring Reactive Project
Create a new Spring WebFlux project using your preferred IDE (e.g., IntelliJ IDEA) with the following options:
- Name: spring-webflux-demo
- Language: Java
- Type: Maven
- Packaging: Jar
Click on the Next button.

Step 2: Add the Dependencies
Add the following dependencies into the spring reactive project.

Project Structure
Once created, the project structure should include standard directories like below:

Step 3: Configure the Application Properties
Add the following property to application.properties file:
spring.application.name=spring-webflux-demoStep 4: Create the ReactiveService Class
package com.gfg.springwebfluxdemo;
import org.springframework.stereotype.Service;
import reactor.core.publisher.Mono;
import reactor.core.scheduler.Schedulers;
@Service
public class ReactiveService {
public Mono<String> getData() {
return Mono.just("Hello, WebFlux!")
.subscribeOn(Schedulers.boundedElastic()); // Run on an elastic thread pool
}
}
This service returns a reactive Mono containing a string, using an elastic scheduler for non-blocking execution.
Step 5: Create the ReactiveController Class
package com.gfg.springwebfluxdemo;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RestController;
import reactor.core.publisher.Mono;
@RestController
public class ReactiveController {
@Autowired
private ReactiveService reactiveService;
@GetMapping("/reactive")
public Mono<String> getReactiveData() {
return reactiveService.getData();
}
}
This controller maps the /reactive endpoint to the ReactiveService, returning a reactive Mono.
Step 6: Main class
No changes are required in the main class.
package com.gfg.springwebfluxdemo;
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
@SpringBootApplication
public class SpringWebfluxDemoApplication {
public static void main(String[] args) {
SpringApplication.run(SpringWebfluxDemoApplication.class, args);
}
}
pom.xml file:
<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="https://maven.apache.org/POM/4.0.0" xmlns:xsi="https://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="https://maven.apache.org/POM/4.0.0 https://maven.apache.org/xsd/maven-4.0.0.xsd">
<modelVersion>4.0.0</modelVersion>
<parent>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-parent</artifactId>
<version>3.3.2</version>
<relativePath/> <!-- lookup parent from repository -->
</parent>
<groupId>com.gfg</groupId>
<artifactId>spring-webflux-demo</artifactId>
<version>0.0.1-SNAPSHOT</version>
<name>spring-webflux-demo</name>
<description>spring-webflux-demo</description>
<url/>
<licenses>
<license/>
</licenses>
<developers>
<developer/>
</developers>
<scm>
<connection/>
<developerConnection/>
<tag/>
<url/>
</scm>
<properties>
<java.version>17</java.version>
</properties>
<dependencies>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-webflux</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-devtools</artifactId>
<scope>runtime</scope>
<optional>true</optional>
</dependency>
<dependency>
<groupId>org.projectlombok</groupId>
<artifactId>lombok</artifactId>
<optional>true</optional>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-test</artifactId>
<scope>test</scope>
</dependency>
<dependency>
<groupId>io.projectreactor</groupId>
<artifactId>reactor-test</artifactId>
<scope>test</scope>
</dependency>
</dependencies>
<build>
<plugins>
<plugin>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-maven-plugin</artifactId>
<configuration>
<excludes>
<exclude>
<groupId>org.projectlombok</groupId>
<artifactId>lombok</artifactId>
</exclude>
</excludes>
</configuration>
</plugin>
</plugins>
</build>
</project>
Step 7: Run the application
Start the application, which will run on port 8080.

Step 8: Testing the Endpoint
Access the endpoint via a GET request:
GET http://localhost:8080/reactiveOutput:

This test verifies that the service correctly returns "Hello, WebFlux!"
This project demonstrates the understanding of the threading model in the Spring WebFlux and Reactor while providing the practical example to the reinforce the concepts of the Spring Reactive Application.