
Reactor에서는 Upstream Publisher에서 emit되는 데이터를 변경하지 않고,
로그 출력, 상태 확인, 디버깅, 로직 트리거 등의 부수 효과(side-effect)를 수행하기 위한 오퍼레이터로 doOnXXX() 계열을 제공한다.
이 오퍼레이터들은 대부분 Consumer<T> 또는 Runnable 인터페이스를 파라미터로 받으며,
리턴값이 없고, 실제 스트림 처리에는 영향을 주지 않는다.
즉, 부수 효과만을 수행하며 스트림의 흐름에는 관여하지 않는다.
doOnError, doOnComplete 등.| Operator | 설명 |
|---|---|
doOnSubscribe | 구독이 시작될 때 실행됨 |
doOnRequest | 요청이 수신될 때 실행됨 |
doOnNext | 데이터가 emit될 때 실행됨 |
doOnComplete | 성공적으로 완료되었을 때 실행됨 |
doOnError | 에러가 발생했을 때 실행됨 |
doOnCancel | 스트림이 취소되었을 때 실행됨 |
doOnTerminate | 완료 또는 에러로 종료되었을 때 실행됨 |
doOnEach | 각 signal 발생 시 마다 실행됨 |
doOnDiscard | Operator에 의해 폐기(discard)된 요소에 대해 실행됨 |
doAfterTerminate | 종료 직후 한 번 실행됨 |
doFirst | 구독 전에 실행됨 (가장 먼저 호출됨) |
doFinally | 성공, 실패 관계없이 최종적으로 무조건 실행됨 |
doOnXXX()는 이러한 부수 효과를 안전하게 스트림 안에서 실행할 수 있도록 돕는다.Flux.range(1, 5)
.doFinally(signalType -> log.info("# doFinally 1: {}", signalType))
.doOnNext(data -> log.info("# range > doOnNext: {}", data))
.doOnRequest(data -> log.info("# doOnRequest: {}", data))
.doOnSubscribe(subscription -> log.info("# doOnSubscribe"))
.doFirst(() -> log.info("# doFirst()"))
.filter(num -> num % 2 == 1)
.doOnNext(data -> log.info("# filter > doOnNext: {}", data))
.doOnComplete(() -> log.info("# doOnComplete()"))
.subscribe(new BaseSubscriber<>() { ... });
doFirst() → doOnSubscribe() → doOnRequest() → doOnNext() (range emit)filter() → doOnNext() (filtered emit) → doOnComplete() → doFinally()