Programação Reativa em Java: Project Reactor e RxJava
Programação reativa é um paradigma de desenvolvimento focado no processamento de fluxos de dados e eventos assíncronos. Em Java, esse paradigma se tornou amplamente difundido graças a bibliotecas que implementam a especificação Reactive Streams. As duas implementações mais populares são Project Reactor (base do Spring WebFlux) e RxJava (Reactive Extensions for Java).
Ao contrário da abordagem imperativa tradicional, a programação reativa permite trabalhar eficientemente com grandes volumes de dados sem bloquear threads de execução. Isso é especialmente importante para aplicações web modernas de alta carga, microsserviços e sistemas de tempo real.
Conceitos fundamentais da programação reativa
Na base da abordagem reativa estão três conceitos-chave:
- Observable (publicador) — fonte de dados que pode gerar eventos (elementos, erros, conclusão).
- Observer (assinante) — consumidor de dados que reage aos eventos.
- Operadores — funções de transformação de fluxos (map, filter, flatMap, combineLatest, etc.).
Os fluxos reativos seguem o princípio de backpressure (contrapressão): o assinante pode informar ao publicador quantos elementos está pronto para processar, prevenindo o estouro de memória.
Project Reactor: Flux e Mono
Project Reactor é uma biblioteca reativa da Pivotal (agora VMware), que está na base do Spring WebFlux. Ela fornece dois tipos principais:
- Flux<T> — fluxo que pode conter 0, 1 ou muitos elementos (sequência assíncrona).
- Mono<T> — fluxo que contém 0 ou 1 elemento (análogo ao Optional, porém assíncrono).
Exemplo: criação e processamento de Flux
import reactor.core.publisher.Flux;import reactor.core.publisher.Mono;
public class ReactorExample { public static void main(String[] args) { // Criando um fluxo a partir de uma lista Flux<String> names = Flux.just("Alice", "Bob", "Charlie", "Diana");
// Aplicando operadores names.filter(name -> name.length() > 3) .map(String::toUpperCase) .subscribe( result -> System.out.println("Recebido: " + result), error -> System.err.println("Erro: " + error), () -> System.out.println("Fluxo concluído") );
// Mono — para um único elemento Mono<String> greeting = Mono.just("Olá, Reativo!"); greeting.subscribe(System.out::println); }}Resultado da execução:
Recebido: ALICERecebido: CHARLIERecebido: DIANAFluxo concluídoOlá, Reativo!RxJava: Observable, Flowable e Single
RxJava é uma implementação do Reactive Extensions (Rx) portada para Java. Na versão 3.x (RxJava 3), estão disponíveis os seguintes tipos principais:
- Observable<T> — fluxo com 0..N elementos, sem suporte a backpressure.
- Flowable<T> — fluxo com 0..N elementos, com suporte a backpressure.
- Single<T> — fluxo com exatamente um elemento ou erro.
- Maybe<T> — fluxo com 0 ou 1 elemento.
- Completable — fluxo sem dados, apenas sinal de conclusão ou erro.
Exemplo: trabalhando com Observable e operadores
import io.reactivex.rxjava3.core.Observable;import io.reactivex.rxjava3.core.Single;
public class RxJavaExample { public static void main(String[] args) { // Criando um Observable a partir de um intervalo de números Observable<Integer> numbers = Observable