Introdução à Programação Reativa
Foto de Luis P.
Por: Luis P.
21 de Janeiro de 2025

Introdução à Programação Reativa

Project Reactor

Java Project Reactor

A programação reativa é um paradigma que trata fluxos de dados assíncronos de maneira declarativa, reagindo a eventos à medida que eles acontecem. Essa abordagem é particularmente útil para sistemas que precisam lidar com grandes volumes de dados ou eventos em tempo real, como APIs de streaming, processamento de dados e microsserviços.

No ecossistema Java, o Project Reactor é uma das implementações mais populares para a programação reativa, compatível com o padrão Reactive Streams.


Por Que Usar o Project Reactor?

  1. Assíncrono e Não Bloqueante: Processa fluxos de dados sem bloquear threads, melhorando a eficiência.
  2. Escalabilidade: Ideal para sistemas que precisam lidar com alta concorrência.
  3. Compatibilidade: Integrado com o Spring WebFlux e outras bibliotecas reativas.
  4. Operadores Poderosos: Oferece dezenas de operadores para manipulação de fluxos de dados.

Principais Abstrações do Project Reactor

1. Mono

Representa um fluxo assíncrono que retorna no máximo um elemento.

Exemplo:

import reactor.core.publisher.Mono;

public class ExemploMono {
    public static void main(String[] args) {
        Mono<String> mono = Mono.just("Olá, Reactor!");

        mono.subscribe(System.out::println);
    }
}

2. Flux

Representa um fluxo assíncrono que pode emitir zero, um ou múltiplos elementos.

Exemplo:

import reactor.core.publisher.Flux;

public class ExemploFlux {
    public static void main(String[] args) {
        Flux<String> flux = Flux.just("A", "B", "C");

        flux.subscribe(System.out::println);
    }
}

Operadores Comuns no Project Reactor

O Reactor oferece uma rica coleção de operadores para transformar, combinar e filtrar fluxos de dados.

1. map

Transforma os elementos do fluxo.

Flux<Integer> numeros = Flux.just(1, 2, 3);
numeros.map(n -> n * n)
       .subscribe(System.out::println);

2. filter

Filtra os elementos com base em uma condição.

Flux<Integer> numeros = Flux.just(1, 2, 3, 4, 5);
numeros.filter(n -> n % 2 == 0)
       .subscribe(System.out::println); // 2, 4

3. flatMap

Mapeia cada elemento para um novo Publisher.

Flux<String> palavras = Flux.just("Reactor", "Java");
palavras.flatMap(palavra -> Flux.fromArray(palavra.split("")))
       .subscribe(System.out::println);

4. reduce

Reduz os elementos para um único valor.

Flux<Integer> numeros = Flux.just(1, 2, 3, 4);
numeros.reduce(0, Integer::sum)
       .subscribe(System.out::println); // 10

Tratamento de Erros

O tratamento de erros no Reactor é realizado com operadores como onErrorResume, onErrorReturn e doOnError.

Exemplo com onErrorReturn

Flux<Integer> flux = Flux.just(1, 2, 3)
    .map(n -> {
        if (n == 2) {
            throw new RuntimeException("Erro no elemento 2");
        }
        return n;
    })
    .onErrorReturn(-1);

flux.subscribe(System.out::println); // 1, -1

Exemplo com onErrorResume

Flux<Integer> flux = Flux.just(1, 2, 3)
    .map(n -> {
        if (n == 2) {
            throw new RuntimeException("Erro no elemento 2");
        }
        return n;
    })
    .onErrorResume(e -> Flux.just(10, 20));

flux.subscribe(System.out::println); // 1, 10, 20

Integração com o Spring WebFlux

O Spring WebFlux é um módulo do Spring Framework baseado no Project Reactor. Ele permite criar APIs não bloqueantes e reativas de maneira eficiente.

Exemplo de Controlador WebFlux

import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RestController;
import reactor.core.publisher.Flux;
import reactor.core.publisher.Mono;

@RestController
public class ExemploController {

    @GetMapping("/mono")
    public Mono<String> getMono() {
        return Mono.just("Olá, Mono!");
    }

    @GetMapping("/flux")
    public Flux<String> getFlux() {
        return Flux.just("Elemento 1", "Elemento 2", "Elemento 3");
    }
}

Ao executar a aplicação, você pode acessar os endpoints:

  • GET /mono: Retorna "Olá, Mono!"
  • GET /flux: Retorna uma lista de elementos.

Boas Práticas na Programação Reativa

  1. Evite Bloqueios: Não use APIs bloqueantes como Thread.sleep ou chamadas síncronas de I/O.
  2. Teste com Cuidados: Utilize bibliotecas específicas, como StepVerifier, para validar fluxos reativos.
  3. Combine Fluxos com Sabedoria: Evite encadeamentos muito complexos que dificultem a leitura e manutenção.
  4. Gerencie Erros com Clareza: Sempre forneça estratégias para lidar com falhas nos fluxos.
  5. Monitore o Desempenho: Ferramentas como Micrometer e Zipkin ajudam a monitorar aplicações reativas.

A programação reativa com o Project Reactor é uma solução poderosa para construir sistemas modernos, assíncronos e escaláveis. Ao dominar as abstrações do Reactor e suas integrações com o Spring WebFlux, você pode criar aplicações que lidam de forma eficiente com eventos em tempo real e altos volumes de dados. Experimente o Reactor em seus projetos e descubra os benefícios da programação reativa no ecossistema Java!

Luis P.
Luis P.
Boa Ventura / PB
Responde em 1 h e 53 min
Identidade verificada
1ª hora grátis
5,0
nota média
1
avaliação
R$ 40
por hora
Graduação: Licenciatura em Computação (UEPB - Universidade Estadual da Paraíba)
Testes em Java, Java para Web, Java - Springboot
Professor de informática, português e inglês. Formado em computação e letras inglês/português. Servidor público aprovado em 3 concursos.

Confira artigos similares

Aprenda sobre qualquer assunto