Mono & Flux
Mono와 Flux는 Spring WebFlux가 기반으로 하는 Project Reactor 라이브러리에서 사용하는 핵심 Publisher 타입입니다.
이 둘은 반응형 스트림(Reactive Stream)에서 데이터의 흐름을 정의하는 역할
모든 비동기 작업은 이 두 타입을 통해 표현되고 처리됨
Mono
Mono는 0개 또는 최대 1개의 결과만을 방출하는 Publisher이다.
신호(Signal)
onNext(T)
: 데이터를 1개 전달(최대 한 번 발생)onComplete()
: 모든 작업이 성공적으로 완료되었음을 알림(onNext
이후 또는 단독으로 발생)onError(Throwable)
: 작업 중 에러 발생을 알림
주요 사용 사례
ID로 단일 데이터 조회 (
findById
)데이터 생성, 수정, 삭제 후 결과 반환
총 개수 세기 (
count
)
// "Hello"라는 단일 데이터를 포함하는 Mono 생성
Mono<String> monoJust = Mono.just("Hello");
// 데이터 없이 작업 완료(onComplete) 신호만 보내는 Mono 생성
Mono<Void> monoEmpty = Mono.empty();
// 에러(onError) 신호만 보내는 Mono 생성
Mono<String> monoError = Mono.error(new RuntimeException("Error occurred"));
Flux
Flux는 0개부터 N개까지, 여러 개의 결과를 스트림 형태로 방출하는 Publisher이다.
신호(Signal)
onNext(T)
: 데이터를 1개 전달(여러 번 발생 가능)onComplete()
: 모든 데이터 스트림이 성공적으로 완료되었음을 알림onError(Throwable)
: 스트림 처리 중 에러 발생을 알림
주요 사용 사례
여러 개의 데이터 목록 조회 (
findAll
)데이터베이스 커서나 메시지 큐로부터 데이터 스트리밍
실시간 이벤트 스트림 (예: 주식 시세, 알림)
// 1, 2, 3, 4, 5 라는 5개의 데이터를 순차적으로 방출하는 Flux 생성
Flux<Integer> fluxJust = Flux.just(1, 2, 3, 4, 5);
// List로부터 Flux 생성
List<String> names = List.of("Alice", "Bob", "Charlie");
Flux<String> fluxFromIterable = Flux.fromIterable(names);
핵심 연산자
Mono와 Flux는 데이터를 가공, 필터링, 조합하기 위한 풍부한 연산자를 제공하며, 이 연산자들은 체인 형태로 연결하여 데이터 파이프라인을 구성할 수 있다.
생성(Creation):
just()
,fromIterable()
,range()
변환(Transformation)
map()
: 동기적인 1:1 변환A
타입의 요소를B
타입으로 변환
flatMap()
: 비동기적인 1:N 변환각 요소를 새로운
Mono
나Flux
로 변환 후, 그 결과를 하나의 스트림으로 평탄화(예:User
객체로Order
목록을 조회)
필터링(Filtering)
filter()
: 주어진 조건(Predicate)을 만족하는 요소만 통과시킴
조합(Combining)
zip()
: 여러 스트림의 요소를 하나씩 짝지어 새로운 스트림 생성merge()
: 여러 스트림을 도착하는 순서대로 하나의 스트림으로 합침
public static void main(String[] args) {
Flux.just(1, 2, 3).map(i -> "Number " + i); // Flux<String>으로 변환
userFlux.flatMap(user -> orderService.getOrders(user.getId())); // Flux<Order>로 변환
Flux.range(1, 10).filter(i -> i % 2 == 0); // 2, 4, 6, 8, 10만 방출
}
구독(Subscribe)하기 전에는 아무 일도 일어나지 않음
Mono
나 Flux
를 생성하고 연산자를 체이닝하는 것은 단지 실행 계획을 만드는 것일 뿐, 실제 데이터의 흐름은 시작되지 않는다.
public static void main(String[] args) {
Flux.range(1, 5)
.doOnNext(num -> System.out.println("데이터 준비: " + num)) // 데이터가 흐를 때 실행
.map(i -> "item-" + i)
.subscribe(result -> System.out.println("최종 결과: " + result)); // 이 코드가 실행되어야 위쪽의 모든 로직이 동작
// 데이터 준비: 1
// 최종 결과: item-1
// 데이터 준비: 2
// 최종 결과: item-2
// ...
}
.subscribe()
메서드가 호출되는 시점에 비로소 데이터가 흐르기 시작하며, Spring WebFlux에서는 프레임워크가 이 역할을 수행하므로 개발자가 직접 호출할 일은 거의 없다.
Last updated
Was this helpful?