
What is Spring Boot WebFlux?
What is Spring Boot WebFlux?
Spring Boot WebFlux is a modern, reactive web framework introduced in Spring 5. It is designed to build non-blocking, asynchronous, and event-driven applications. Traditional Spring MVC follows a blocking model where each request occupies one thread until the response is returned. WebFlux, on the other hand, uses a reactive programming model, which makes it highly efficient for handling a large number of concurrent requests.
With the growing demand for high-performance applications, microservices, real-time streaming, and cloud-native systems, Spring Boot WebFlux has become an important skill for Java developers.
Why WebFlux?
Before WebFlux, Spring MVC worked perfectly for most applications. However, with high traffic systems like:
- Real-time chat applications
- Live notifications
- Streaming APIs
- IoT applications
- High-concurrency microservices
The traditional thread-per-request model becomes inefficient.
Problems with Spring MVC
- One thread is blocked per request
- Poor scalability under heavy load
- Inefficient resource usage
Advantages of Spring WebFlux
- Non-blocking I/O
- Uses fewer threads
- Better performance under heavy load
- Ideal for reactive and streaming applications
- Works well with cloud and microservices architecture
What is Reactive Programming?
A declarative programming style called reactive programming emphasizes:
- Asynchronous data streams
- Event-driven execution
- Handling data as it arrives
Instead of waiting for a response, the system reacts when data becomes available.
Key Concepts
- Asynchronous
- Non-blocking
- Backpressure (handling data flow speed)
Core Components (Reactive Streams)
Reactive Programming is based on the Publisher–Subscriber model, where data flows as a stream, and components react to it.
1. Publisher
- A Publisher produces data.
- It does not send data until requested by a Subscriber.
- Examples in Spring WebFlux:
- Mono<T> → emits 0 or 1 item
- Flux<T> → emits 0 to N items
Example:
Flux<Integer> numbers = Flux.just(1, 2, 3, 4);
2. Subscriber
- A Subscriber consumes data emitted by the Publisher.
- It defines how to handle:
- Incoming data
- Errors
- Completion
Example:
numbers.subscribe(
data -> System.out.println(data),
error -> System.out.println("Error: " + error),
() -> System.out.println("Completed")
);
Subscription
- A Subscription connects Publisher and Subscriber.
- It controls:
- How much data the Subscriber wants
- Cancellation of the stream
This enables backpressure.
4. Backpressure
- Backpressure means the Subscriber controls the speed of data flow.
- Keeps the system from becoming overloaded when data is generated more quickly than it can be used.
Example scenario:
A fast database sending 1 million records, but the client can process only 100 at a time.
Reactive streams handle this safely.
5. Processor (Optional)
- Acts as both:
- Subscriber (receives data)
- Publisher (transforms and emits data)
Used for data transformation pipelines.
Reactive Programming Flow
Publisher → Subscription → Subscriber
- Data flows asynchronously
- Execution is non-blocking
- The system reacts to data as it arrives
Core Reactive Types in WebFlux
Spring WebFlux is built on Project Reactor, which provides two main reactive types:
1. Mono
- Represents 0 or 1 value
- Used for single response
Mono<String>
2. Flux
- Represents 0 to N values
- Used for multiple responses or streams
Flux<String>
WebFlux Execution Model
WebFlux can run on:
- Netty (default)
- Servlet 3.1+ containers (Tomcat, Jetty)
Netty is preferred because it is fully non-blocking.
How WebFlux Handles Requests
- Client sends a request
- Request is handled by an event loop
- No thread is blocked
- Data is processed asynchronously
- Response is sent when ready
Creating a Spring Boot WebFlux Application
Dependencies Required
- Spring Reactive Web (WebFlux)
Maven dependency:
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-webflux</artifactId>
</dependency>
- Spring data r2dbc
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-data-r2dbc</artifactId>
</dependency>
<dependency>
<groupId>io.asyncer</groupId>
<artifactId>r2dbc-mysql</artifactId>
<scope>runtime</scope>
</dependency>
Example Program – Reactive REST API
Requirement
Create a REST API that returns a list of users using WebFlux.
Entity Class(com.model)
import org.springframework.data.annotation.Id;
import org.springframework.data.relational.core.mapping.Table;
@Table("actor")
public class Actor {
@Id
private int actorId;//We don't need to give autoincrement it automatically leaves.
private String actorName;
private String movie;
public Actor() {
super();
}
public Actor(int actorId, String actorName, String movie) {
super();
this.actorId = actorId;
this.actorName = actorName;
this.movie = movie;
}
public int getActorId() {
return actorId;
}
public void setActorId(int actorId) {
this.actorId = actorId;
}
public String getActorName() {
return actorName;
}
public void setActorName(String actorName) {
this.actorName = actorName;
}
public String getMovie() {
return movie;
}
public void setMovie(String movie) {
this.movie = movie;
}
}
Repository (com.dao)
@Repository
public interface ActorRepository extends ReactiveCrudRepository<Actor, Integer> {
}
Service
public interface ActorService {
public Flux<Actor> getAllActors();
public Mono<Actor> getActorById(Integer id);
public Mono<Actor> saveActor(Actor actor);
public Mono<Void> deleteActor(Integer id);
}
Explore Other Demanding Courses
No courses available for the selected domain.
@Service
public class ActorServiceImpl implements ActorService {
@Autowired
private ActorRepository actorRepository;
public Flux<Actor> getAllActors() {
return actorRepository.findAll();
}
public Mono<Actor> getActorById(Integer id) {
return actorRepository.findById(id);
}
public Mono<Actor> saveActor(Actor actor) {
return actorRepository.save(actor);
}
public Mono<Void> deleteActor(Integer id) {
return actorRepository.deleteById(id);
}
}
Controller Class
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RestController;
import reactor.core.publisher.Flux;
import java.time.Duration;
import java.util.List;
@RestController
public class ActorController {
@Autowired
private ActorService actorService;
@GetMapping("/getAll")
public Flux<Actor> getAllActors() {
return actorService.getAllActors()
.delayElements(Duration.ofSeconds(1)); //Adds a 1-second delay between each emitted Actor After emitting Actor1 → waits 1 second → emits Actor2 → waits 1 second → emits Actor3
}
@GetMapping("/get/{id}")
public Mono<Actor> getBookById(@PathVariable Integer id) {
return actorService.getActorById(id);
}
@PostMapping("/add")
public Mono<Actor> createActor(@RequestBody Actor actor) {
return actorService.saveActor(actor);
}
@DeleteMapping("/delete/{id}")
public Mono<Void> deleteActor(@PathVariable Integer id) {
return actorService.deleteActor(id);
}
}
Explanation of Code
- public Mono<Actor> createActor(@RequestBody Actor actor) :
- Accepts actor data from the request body and returns the saved actor reactively.
- Flux<Actor> Fetches all actors reactively and emits each actor with a 1-second non-blocking delayFlux.fromIterable() converts a list into a reactive stream
- . public Mono<Actor> getBookById(@PathVariable Integer id) :
Returns one Actor asynchronously using Mono. No thread is blocked during execution
- public Mono<Void> deleteActor(@PathVariable Integer id)
Returns a reactive signal indicating completion of the delete operation.
Application Output
When you hit:
http://localhost:8082/getAll
[{"actorId":1,"actorName":"ajay","movie":"Dar"},{"actorId":2,"actorName":"Vijay","movie":"Jawan"},{"actorId":3,"actorName":"Sanjay","movie":"Judha"},{"actorId":4,"actorName":"Ravi","movie":"humsafar"}]
Backpressure in WebFlux
Backpressure refers to the consumer's control over the amount of data it wants to receive.
WebFlux automatically handles backpressure using Reactive Streams specification.
When to Use WebFlux
Use WebFlux if:
- High concurrency is required
- Streaming data is involved
- Microservices architecture
- Real-time applications
- Cloud-native systems
Avoid WebFlux if:
- Simple CRUD application
- Blocking database drivers
- The team is not familiar with reactive programming
WebFlux with Database
For true non-blocking behavior, use:
- R2DBC instead of JPA
- Reactive MongoDB
- Reactive Cassandra
So, we can conclude that Spring Boot WebFlux is a powerful framework for building high-performance and scalable reactive applications.
It is not a replacement for Spring MVC, but a better choice for applications that require non-blocking behavior and high concurrency.
Learning WebFlux gives Java developers a strong advantage in modern backend development, especially in microservices and cloud-based systems.
Do visit our channel to explore more: SevenMentor