리액티브 스트림즈, Mono, 그리고 Flux

2023. 7. 14. 19:27Spring/webflux

728x90

Mono

0 또는 1개의 결과를 가지는 데이터 스트림

서블릿 스택에서의 Optional과 유사

 

Flux

0개 이상의 데이터 방출

서블릿 스택에서의 List와 유사

 

리액티브 스트림즈 핵심 컴포넌트

Publisher :

스트림 데이터를 생성/방출 

subscriber에게 데이터 전달

Mono와 Flux도 Publsiher 타입

Subscriber :

Publisher에 방출된 데이터를 처리

publisher에게 받은 데이터를 소비하거나 다른 작업 수행 가능, 백프레셔를 통해 데이터 흐름 조절 가능

subscription :

Publisher와 Subscriber 간의 연결을 나타냄. Subscriber는 Subscription을 통해 Publisher의 데이터를 요청/취소 가능

Processor :

Publisher와 Subscriber 역할을 동시에 수행

데이터 중간 처리 단계에서 유용

 

Mono/Flux 사용 예

 

Mono test

    @Test
    @DisplayName("Mono가 생성")
    void createMono() {
        Mono<String> sample = Mono.just("Hello, world");
        log.info("블로킹하여 데이터 가져오기 {}", sample.block());
        sample.map(i -> i + " : 추가추가")
                .doOnNext(i -> log.info("doOnNext : 스트림에 부가적인 수행 {}", i))
                .doOnSuccess(i -> log.info("doOnSuccess : 성공적으로 데이터를 처리했을 때 수행 {}", i))
                .doOnSubscribe(i -> log.info("doOnSubscribe : 구독하는 시점에 수행"))
                .subscribe();
    }

실행 결과

블로킹하여 데이터 가져오기 Hello, world
doOnSubscribe : 구독하는 시점에 수행
doOnNext : 스트림에 부가적인 수행 Hello, world : 추가추가
doOnSuccess : 성공적으로 데이터를 처리했을 때 수행 Hello, world : 추가추가

Flux test

    @Test
    @DisplayName("Flux 생성")
    void createFlux() {
        Flux<String> sample = Flux.just("요소1", "요소2", "요소3");
        log.info("블로킹하여 첫 데이터 가져오기 {}", sample.blockFirst());
        log.info("블로킹하여 마지막 데이터 가져오기 {}", sample.blockLast());
        sample.map(i -> i + " : 추가추가")
                .doOnNext(i -> log.info("doOnNext : 스트림에 부가적인 수행 {}", i))
                .doOnComplete(() -> log.info("doOnComplete : 성공적으로 데이터를 처리를 완료 했을 때 수행 "))
                .doOnSubscribe(i -> log.info("doOnSubscribe : 구독하는 시점에 수행"))
                .subscribe();
    }

실행 결과 

블로킹하여 첫 데이터 가져오기 요소1
블로킹하여 마지막 데이터 가져오기 요소3
doOnSubscribe : 구독하는 시점에 수행
doOnNext : 스트림에 부가적인 수행 요소1 : 추가추가
doOnNext : 스트림에 부가적인 수행 요소2 : 추가추가
doOnNext : 스트림에 부가적인 수행 요소3 : 추가추가
doOnComplete : 성공적으로 데이터를 처리를 완료 했을 때 수행

Mono/Flux는 Controller 단에서도 사용 가능하다.

@RestController
public class HelloController {
    
    @GetMapping("mono")
    public Mono<String> getMono() {
        return Mono.just("Mono 입니다");
    }

    @GetMapping("flux")
    public Flux<String> getFlux() {
        return Flux.just("F1", "F2", "F3");
    }
}

실행 결과

728x90