Reaktywny dostęp do danych i integracja
Proszę łączyć aplikacje WebFlux z reaktywnymi magazynami danych oraz integrować je z innymi komponentami reaktywnymi.
Reaktywny dostęp do danych i integracja to bezpłatna lekcja Spring Boot 4 Complete Guide na CoddyKit. To lekcja 3 z 4. Możesz przeczytać całą lekcję poniżej za darmo — a potem ćwiczyć ją interaktywnie w przeglądarce z wbudowanym edytorem kodu i tutorem AI dostępnym 24/7. To część ścieżki edukacyjnej Spring Boot 4 Complete Guide, a Twój postęp synchronizuje się między webem a aplikacją CoddyKit. Kurs Spring Boot 4 Complete Guide zawiera 4 lekcji w sumie.
Części tej lekcji nie zostały jeszcze przetłumaczone i są wyświetlane po angielsku.
Reactive Data Access Needs
When building reactive applications with Spring WebFlux, traditional data access methods like Spring Data JPA or plain JDBC won't work. Why?
These methods are blocking. They pause the application thread while waiting for database operations to complete. This goes against the non-blocking, asynchronous nature of reactive programming.
Introducing Reactive Data Stores
To maintain the reactive flow, we need reactive data stores and drivers that support non-blocking I/O. These drivers return Mono or Flux, allowing your application to do other work while the database processes requests.
Common reactive databases include:
- MongoDB: A NoSQL document database.
- Cassandra: A NoSQL wide-column store.
- Redis: A NoSQL key-value store, often used for caching.
- R2DBC: (Reactive Relational Database Connectivity) for relational databases like PostgreSQL, MySQL, H2.
Setting Up Reactive MongoDB
For our examples, we'll focus on MongoDB, a popular choice for reactive applications. First, you need the right dependency in your pom.xml (Maven) or build.gradle (Gradle):
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-data-mongodb-reactive</artifactId>
</dependency>This starter brings in Spring Data MongoDB Reactive, allowing you to easily interact with MongoDB in a non-blocking way.
Defining Reactive Entities
Just like with traditional Spring Data, you define entities that map to your database collections. For MongoDB, you use the @Document annotation.
The @Id annotation marks the primary key field. This tells Spring Data how to identify unique documents.
import org.springframework.data.annotation.Id;
import org.springframework.data.mongodb.core.mapping.Document;
@Document(collection = "products")
public class Product {
@Id
private String id;
private String name;
private double price;
public Product(String id, String name, double price) {
this.id = id;
this.name = name;
this.price = price;
}
// Getters and Setters (omitted for brevity)
public String getId() { return id; }
public String getName() { return name; }
public double getPrice() { return price; }
@Override
public String toString() {
return "Product{id='" + id + "', name='" + name + "'}";
}
}Creating Reactive Repositories
To perform CRUD operations (Create, Read, Update, Delete) on your entities, you create repository interfaces. For reactive MongoDB, you extend ReactiveMongoRepository.
This interface automatically provides reactive versions of common operations, returning Mono for single results and Flux for multiple results.
import org.springframework.data.mongodb.repository.ReactiveMongoRepository;
import reactor.core.publisher.Flux;
import reactor.core.publisher.Mono;
public interface ProductRepository extends ReactiveMongoRepository<Product, String> {
// Custom reactive query methods can be added here
Mono<Product> findByName(String name);
Flux<Product> findByPriceGreaterThan(double price);
}Simulating Reactive Save
When you save an entity using a reactive repository, it returns a Mono<Product>. This Mono represents the product once it's saved. You subscribe to it to trigger the operation and handle the result.
Try running this example to see how a reactive save operation might be handled:
import reactor.core.publisher.Mono;
class Item {
String id;
String name;
public Item(String id, String name) {
this.id = id;
this.name = name;
}
@Override
public String toString() { return "Item{name='" + name + "'} "; }
}
public class Main {
public static void main(String[] args) {
Item newItem = new Item("101", "Reactive Widget");
// Simulate a reactive repository save method
Mono<Item> savedItemMono = Mono.just(newItem)
.doOnSuccess(item -> System.out.println("Simulating DB save for: " + item.name));
System.out.println("Initiating save operation...");
savedItemMono.subscribe(
item -> System.out.println("Saved item received: " + item),
error -> System.err.println("Error: " + error.getMessage()),
() -> System.out.println("Save process completed.")
);
}
}Simulating Reactive Retrieval
Retrieving data reactively works similarly. For a single item (e.g., by ID), you get a Mono. For multiple items, you get a Flux. You subscribe to these publishers to consume the data.
Run this code to see how Mono and Flux are used to handle retrieved data:
import reactor.core.publisher.Flux;
import reactor.core.publisher.Mono;
import java.util.Arrays;
import java.util.List;
class User {
String id;
String name;
public User(String id, String name) {
this.id = id;
this.name = name;
}
@Override
public String toString() { return "User{name='" + name + "'} "; }
}
public class Main {
public static void main(String[] args) {
List<User> users = Arrays.asList(
new User("U1", "Alice"),
new User("U2", "Bob"),
new User("U3", "Charlie")
);
// Simulate finding a single user by ID
Mono<User> userMono = Mono.just(users.get(0));
System.out.println("\n--- Finding single user ---");
userMono.subscribe(user -> System.out.println("Found: " + user));
// Simulate finding all users
Flux<User> userFlux = Flux.fromIterable(users);
System.out.println("\n--- Finding all users ---");
userFlux.subscribe(user -> System.out.println("Found: " + user));
}
}Integrating with Reactive Services
In a Spring WebFlux application, your service layer will inject the reactive repositories and use their Mono and Flux return types. This allows for seamless chaining of reactive operations.
For example, a service method might save a product and then return the saved product's ID, all within a reactive stream.
import reactor.core.publisher.Mono;
// Assume Product and ProductRepository are defined elsewhere
// import your.package.Product;
// import your.package.ProductRepository;
// This is a simplified example, not a full runnable app
// as it would require a full Spring Boot context.
class ProductService {
private final ProductRepository productRepository;
public ProductService(ProductRepository productRepository) {
this.productRepository = productRepository;
}
public Mono<String> createProduct(Product product) {
return productRepository.save(product)
.map(Product::getId);
}
public Mono<Product> getProductById(String id) {
return productRepository.findById(id);
}
}Chaining Reactive Data Operations
The true power of reactive data access comes when you chain operations. You can transform, filter, and combine Mono and Flux streams from your database with other reactive sources (like external API calls or other service logic).
This allows you to build complex, non-blocking data flows efficiently.
import reactor.core.publisher.Flux;
import reactor.core.publisher.Mono;
import java.time.Duration;
public class Main {
public static void main(String[] args) {
// Simulate fetching user IDs from a database (Flux)
Flux<String> userIds = Flux.just("userA", "userB", "userC");
// Simulate fetching user details for each ID (Mono)
Flux<String> userNames = userIds.delayElements(Duration.ofMillis(50))
.flatMap(id -> Mono.just("Name_" + id.toUpperCase()));
System.out.println("Fetching and transforming user data...");
userNames.subscribe(
name -> System.out.println("Processed User: " + name),
error -> System.err.println("Error: " + error.getMessage()),
() -> System.out.println("All users processed.")
);
// Keep main thread alive for async operations
try { Thread.sleep(500); } catch (InterruptedException e) {}
}
}Quick Check: Reactive Repositories
You are building a Spring WebFlux application and need to connect to a MongoDB database in a non-blocking way. Which Spring Data interface should you extend for your repository to get reactive CRUD operations?
Recap: Reactive Data Access
Great job! In this lesson, you've learned about the importance of reactive data access in Spring WebFlux applications and how to achieve it.
- Traditional blocking data access is replaced by non-blocking reactive drivers.
- Spring Data provides interfaces like
ReactiveMongoRepositoryfor reactive CRUD. - These repositories return
Mono(for single items) andFlux(for multiple items). - You can seamlessly chain reactive operations from data access with other reactive components.
This knowledge is key to building truly end-to-end reactive applications!
Często zadawane pytania
Czy lekcja „Reaktywny dostęp do danych i integracja” jest bezpłatna?
Tak — pełny tekst „Reaktywny dostęp do danych i integracja” jest dostępny za darmo tutaj w sieci. Aby ćwiczyć ją interaktywnie (wbudowany edytor kodu i tutor AI dostępny 24/7) i odblokować resztę kursu Spring Boot 4 Complete Guide, przejdź na CoddyKit PRO. Kurs Spring Boot 4 Complete Guide zawiera 4 lekcji w sumie.
Co nauczysz się w „Reaktywny dostęp do danych i integracja”?
Proszę łączyć aplikacje WebFlux z reaktywnymi magazynami danych oraz integrować je z innymi komponentami reaktywnymi. Ćwiczysz Spring Boot 4 Complete Guide z praktycznym kodem, który uruchamiasz bezpośrednio w przeglądarce, a tutor AI dostępny 24/7 odpowiada na Twoje pytania podczas pracy nad lekcją.
Czy potrzebuję doświadczenia, aby zacząć Spring Boot 4 Complete Guide?
Nie wymagamy żadnego doświadczenia. Spring Boot 4 Complete Guide w CoddyKit jest strukturyzowany dla początkujących i zaawansowanych użytkowników, więc możesz zacząć tutaj lub od początku i uczyć się w swoim tempie. To lekcja 3 z 4.
Ile czasu zajmuje lekcja „Reaktywny dostęp do danych i integracja”?
Większość lekcji CoddyKit trwa około 5–10 minut. Każda lekcja to mały, interaktywny krok, dzięki czemu robisz systematyczne postępy i zawsze wracasz dokładnie do tego samego miejsca — na webie i w aplikacji.
Czy mogę pisać i uruchamiać kod w tej lekcji Spring Boot 4 Complete Guide?
Tak. Każda lekcja Spring Boot 4 Complete Guide zawiera wbudowany edytor kodu, więc piszesz i uruchamiasz prawdziwy kod bezpośrednio w przeglądarce i od razu otrzymujesz sprzężenie zwrotne od AI — bez konfiguracji na komputerze.
Wszystkie lekcje w tym kursie
- Wprowadzenie do programowania reaktywnego
- Spring WebFlux i Reactor Core
- Reaktywny dostęp do danych i integracja
- Kontrola przeciążenia i obsługa błędów w strumieniach reaktywnych