Programación reactiva en Java: Project Reactor y RxJava
La programación reactiva es un paradigma de desarrollo orientado al procesamiento de flujos de datos y eventos asíncronos. En Java, este paradigma se ha extendido ampliamente gracias a las bibliotecas que implementan la especificación Reactive Streams. Las dos implementaciones más populares son Project Reactor (base de Spring WebFlux) y RxJava (Reactive Extensions for Java).
A diferencia del enfoque imperativo tradicional, la programación reactiva permite trabajar eficientemente con grandes volúmenes de datos sin bloquear los hilos de ejecución. Esto es especialmente importante para aplicaciones web modernas de alta carga, microservicios y sistemas en tiempo real.
Conceptos fundamentales de la programación reactiva
En el núcleo del enfoque reactivo se encuentran tres conceptos clave:
- Observable (publicador) — fuente de datos que puede generar eventos (elementos, errores, finalización).
- Observer (suscriptor) — consumidor de datos que reacciona a los eventos.
- Operadores — funciones de transformación de flujos (map, filter, flatMap, combineLatest, etc.).
Los flujos reactivos siguen el principio de backpressure (contrapresión): el suscriptor puede indicar al publicador cuántos elementos está dispuesto a procesar, evitando así el desbordamiento de memoria.
Project Reactor: Flux y Mono
Project Reactor es una biblioteca reactiva de Pivotal (ahora VMware) que forma la base de Spring WebFlux. Proporciona dos tipos principales:
- Flux<T> — flujo que puede contener 0, 1 o muchos elementos (secuencia asíncrona).
- Mono<T> — flujo que contiene 0 o 1 elemento (análogo a Optional, pero asíncrono).
Ejemplo: creación y procesamiento de Flux
import reactor.core.publisher.Flux;import reactor.core.publisher.Mono;
public class ReactorExample { public static void main(String[] args) { // Creamos un flujo a partir de una lista Flux<String> names = Flux.just("Alice", "Bob", "Charlie", "Diana");
// Aplicamos operadores names.filter(name -> name.length() > 3) .map(String::toUpperCase) .subscribe( result -> System.out.println("Recibido: " + result), error -> System.err.println("Error: " + error), () -> System.out.println("Flujo completado") );
// Mono — para un solo elemento Mono<String> greeting = Mono.just("¡Hola, Reactivo!"); greeting.subscribe(System.out::println); }}Resultado de la ejecución:
Recibido: ALICERecibido: CHARLIERecibido: DIANAFlujo completado¡Hola, Reactivo!RxJava: Observable, Flowable y Single
RxJava es una implementación de Reactive Extensions (Rx) portada a Java. En la versión 3.x (RxJava 3) están disponibles los siguientes tipos principales:
- Observable<T> — flujo con 0..N elementos, sin soporte de backpressure.
- Flowable<T> — flujo con 0..N elementos, con soporte de backpressure.
- Single<T> — flujo con exactamente un elemento o un error.
- Maybe<T> — flujo con 0 o 1 elemento.
- Completable — flujo sin datos, solo señal de finalización o error.
Ejemplo: trabajo con Observable y operadores
import io.reactivex.rxjava3.core.Observable;import io.reactivex.rxjava3.core.Single;
public class RxJavaExample { public static void main(String[] args) { // Creamos un Observable a partir de un rango de números Observable<Integer> numbers = Observable