Spring Boot - Reactive Programming Using Spring Webflux Framework
Last Updated :
23 Jul, 2025
In this article, we will explore React programming in Spring Boot, Reactive programming is an asynchronous, non-blocking programming paradigm for developing highly responsive applications that react to external stimuli.
What is Reactive Programming
- In reactive programming, the flow of data is asynchronous through push-based publishers and subscribers instead of synchronous pull-based calls.
- The core abstraction in reactive programming is the reactive stream which provides a standard way to work with asynchronous streams of data. The two primary reactive stream interfaces are Publisher and Subscriber.
- Publishers push data to Subscribers asynchronously. Subscribers register callbacks and are notified when new data arrives instead of actively polling for it.
- Examples of reactive streams include Mono and Flux in Spring Webflux. Mono represents a single event/value and Flux represents a stream of multiple values.
Benefits of Reactive Programming with Spring Webflux
- Support for Reactive Types
- Integration with Reactive Streams
- Non-blocking I/O
- Microservices-friendly
Spring Webflux Dependency
Gradle:
dependencies {
implementation 'org.springframework.boot:spring-boot-starter-webflux'
}Maven:
<!-- https://mvnrepository.com/artifact/org.springframework/spring-webflux -->
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-webflux</artifactId>
<version>6.1.3</version>
</dependency>
Reactive Types in Spring Webflux
- Mono: Mono specifically represents a single value or no value at all
- Flux: Flux represents a **stream of zero or more elements** emitted over time
Step By Step Implementation
Step 1: Set up a new Spring MVC project
Create a new Maven project in your preferred IDE (e.g., IntelliJ or Eclipse or Spring Tool Suite) and add the following dependencies.
- Spring Webflux
- Mongo Db - for Database
- Lombok
XML
<?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.2.2</version>
<relativePath/> <!-- lookup parent from repository -->
</parent>
<groupId>com.example</groupId>
<artifactId>REST_Spring_Flux</artifactId>
<version>0.0.1-SNAPSHOT</version>
<name>REST_Spring_Flux</name>
<description>Demo project for Spring Boot</description>
<properties>
<java.version>17</java.version>
</properties>
<dependencies>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-data-mongodb-reactive</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-webflux</artifactId>
</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>
Project Structure:

Step 2: Configure Mongo Db Database
# MongoDB properties
spring.data.mongodb.host=localhost
spring.data.mongodb.port=27017
spring.data.mongodb.database=student_management
- host: host property pecifies the hostname or IP address of the MongoDB server. In this example we are using localhost.
- port: property defines the port number on which the MongoDB server is running. In this example we are running our server on port no : 27010 [8080].
- database: sets the name of the MongoDB database that our Spring Boot application will connect to. In this example, the database name is "student_management".
Step 3: Create Model Class
Student.class File:
Java
package com.example.demo.entities;
import org.springframework.data.annotation.Id;
import org.springframework.data.mongodb.core.mapping.Document;
@Document
public class Student {
@Id private String id;
private String name;
private int age;
public Student(String id, String name, int age)
{
super();
this.id = id;
this.name = name;
this.age = age;
}
public Student()
{
super();
// TODO Auto-generated constructor stub
}
public String getId() { return id; }
public void setId(String id) { this.id = id; }
public String getName() { return name; }
public void setName(String name) { this.name = name; }
public int getAge() { return age; }
public void setAge(int age) { this.age = age; }
}
Note: @Document annotation indicate that this class should be mapped to a MongoDB document.
Step 4: Create Repository Interface
StudentRepository.class File:
Java
package com.example.demo.repositories;
import com.example.demo.entities.*;
import org.springframework.data.mongodb.repository.ReactiveMongoRepository;
public interface StudentRepository
extends ReactiveMongoRepository<Student, String> {
}
Step 5: Create Controller
StudentController.class File:
Java
package com.example.demo.controller;
import com.example.demo.entities.Student;
import com.example.demo.services.StudentService;
import org.springframework.web.bind.annotation.DeleteMapping;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.PathVariable;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.RequestBody;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;
import reactor.core.publisher.Flux;
import reactor.core.publisher.Mono;
@RestController
@RequestMapping("/api/students")
public class StudentController {
private final StudentService studentService;
public StudentController(StudentService studentService)
{
this.studentService = studentService;
}
public Mono<Student>
saveStudent(@RequestBody Student student)
{
return studentService.saveStudent(student);
}
@GetMapping public Flux<Student> getAllStudents()
{
return studentService.getAllStudents();
}
@GetMapping("/{id}")
public Mono<Student>
getStudentById(@PathVariable String id)
{
return studentService.getStudentById(id);
}
@PostMapping
public Mono<Student>
createStudent(@RequestBody Student student)
{
return studentService.saveStudent(student);
}
@DeleteMapping("/{id}")
public Mono<Void> deleteStudent(@PathVariable String id)
{
return studentService.deleteStudent(id);
}
}
Step 6: Create Service Interface
StudentService.class File:
Java
package com.example.demo.services;
import com.example.demo.entities.*;
import reactor.core.publisher.Flux;
import reactor.core.publisher.Mono;
public interface StudentService {
Mono<Student> saveStudent(Student student);
Flux<Student> getAllStudents();
Mono<Student> getStudentById(String id);
Mono<Void> deleteStudent(String id);
}
Step 7: Create ServiceImpl
StudentServiceImpl.class File:
Java
package com.example.demo.services;
import com.example.demo.entities.*;
import com.example.demo.repositories.StudentRepository;
import org.springframework.stereotype.Service;
import reactor.core.publisher.Flux;
import reactor.core.publisher.Mono;
@Service
public class StudentServiceImpl implements StudentService {
private final StudentRepository studentRepository;
public StudentServiceImpl(
StudentRepository studentRepository)
{
this.studentRepository = studentRepository;
}
@Override
public Mono<Student> saveStudent(Student student)
{
return studentRepository.save(student);
}
@Override public Flux<Student> getAllStudents()
{
return studentRepository.findAll();
}
@Override public Mono<Student> getStudentById(String id)
{
return studentRepository.findById(id);
}
@Override public Mono<Void> deleteStudent(String id)
{
return studentRepository.deleteById(id);
}
}
Step 8: Run the Application
Now, You can run the Spring Boot application from IDE or by using the command-line tool provided by Spring Boot.
mvn spring-boot:run
Step 9: Test the Endpoints Using Postman
POST: http://localhost:8080/api/students-- Post the student data
GET: http://localhost:8080/api/students-- Get all student details
GET: http://localhost:8080/api/students/{id} -- Get the student details by Id
Output:
Explore
Spring Boot Basics and Prerequisites
Spring Boot Core
Spring Boot with REST API
Spring Boot with Database and Data JPA
Spring Boot with Kafka
Spring Boot with AOP