What are the four interfaces defined by the Reactive Streams specification, and what is each responsible for?
answer
- Publisher / Subscriber / Subscription / Processor
- subscribe returns void; Subscription arrives via onSubscribe
- Processor = Subscriber + Publisher
- org.reactivestreams package, vendor-neutral
- Flux/Mono ARE Publishers
basics
~10 sPublisher produces data, Subscriber consumes it, Subscription links the two and lets the Subscriber request items or cancel, and Processor is both a Subscriber and a Publisher (a middle stage).
solid answer
~40 sReactive Streams defines four interfaces in the org.reactivestreams package. Publisher<T> has a single method subscribe(Subscriber). Subscriber<T> has onSubscribe(Subscription), onNext(T), onError(Throwable), onComplete(). Subscription has request(long n) and cancel(); it is the private channel between one Publisher and one Subscriber that carries demand upstream and cancellation upstream. Processor<T,R> extends both Subscriber<T> and Publisher<R>, representing an intermediate processing stage that consumes one stream and produces another. Reactor's Flux and Mono are Publisher implementations; Spring WebFlux uses these interfaces as the common contract so any compliant library (Reactor, RxJava, Akka Streams) interoperates. The whole point is a standard, vendor-neutral handshake for asynchronous stream processing with flow control.
code
java · 21 lines// The four Reactive Streams interfaces (org.reactivestreams), paraphrased:
public interface Publisher<T> {
void subscribe(Subscriber<? super T> s);
}
public interface Subscriber<T> {
void onSubscribe(Subscription s); // exactly once, first
void onNext(T t); // 0..N times
void onError(Throwable t); // terminal
void onComplete(); // terminal
}
public interface Subscription {
void request(long n); // signal demand upstream
void cancel(); // stop and release
}
public interface Processor<T, R> extends Subscriber<T>, Publisher<R> {}
// Reactor's Flux IS a Publisher, so this is legal:
org.reactivestreams.Publisher<String> pub = reactor.core.publisher.Flux.just("a", "b");go deeper
Must name all four interfaces and roughly what each does.
Should know the exact method signatures and that subscribe returns void.
Explains the interop rationale and how Reactor maps onto these interfaces.
Discusses the interface set as an integration contract across libraries and the JDK Flow mirror.
**Reactive Streams** is a small specification (just four Java interfaces plus a written rule set) that standardizes asynchronous stream processing with non-blocking flow control. It lives in the `org.reactivestreams` package (artifact `org.reactivestreams:reactive-streams`). Spring WebFlux, Project Reactor (Flux/Mono), and RxJava all implement it so they can interoperate. The four interfaces: 1. **`Publisher<T>`** — the source of a potentially unbounded sequence of elements. Its only method is `void subscribe(Subscriber<? super T> s)`. A Publisher is passive: it does nothing until subscribed to (this is why Reactor pipelines are 'cold' and only run when subscribed). A Publisher may serve multiple Subscribers; each subscription is independent. 2. **`Subscriber<T>`** — the consumer. It has exactly four callback methods: - `onSubscribe(Subscription s)` — called first, exactly once, handing the Subscriber its private control channel. - `onNext(T t)` — delivers one element; called zero-to-many times. - `onError(Throwable t)` — terminal; signals failure. - `onComplete()` — terminal; signals successful end. 3. **`Subscription`** — the one-to-one contract token between a single Publisher and a single Subscriber. It has: - `request(long n)` — the Subscriber tells the Publisher it is ready to receive up to `n` more elements (this is the demand / flow-control mechanism). - `cancel()` — the Subscriber asks the Publisher to stop sending and release resources. The Subscription is what makes the stream *pull-and-push*: elements are pushed by the Publisher, but only up to the amount the Subscriber has pulled via `request`. 4. **`Processor<T,R>`** — `extends Subscriber<T>, Publisher<R>`. It is a stage that is simultaneously a Subscriber (of an upstream) and a Publisher (to a downstream) — e.g., a transformation or a bridge. In practice application developers rarely implement Processor directly; Reactor's operators (`map`, `filter`, etc.) fill this role internally, and `Sinks` largely replaced the older `Processor` implementations (`DirectProcessor`, `UnicastProcessor` are deprecated). **Why it matters in Spring:** WebFlux controllers return `Flux`/`Mono` (Reactor Publishers), but the framework only depends on the `Publisher` interface, so a controller could return an RxJava `Flowable` and it still works. This interface set is the lingua franca. **Gotcha:** `Publisher.subscribe` returns `void`, not the Subscription — the Subscription is delivered *to the Subscriber* via `onSubscribe`. Nothing flows until the Subscriber calls `request(n)`. **Note:** The JDK later mirrored these exact interfaces as `java.util.concurrent.Flow.Publisher/Subscriber/Subscription/Processor` (Java 9+); they are semantically identical, and adapters bridge the two.
- Why does Publisher.subscribe return void instead of the Subscription?Because subscription is asynchronous: the Publisher may need to do setup before it can hand back a control channel. It delivers the Subscription to the Subscriber via onSubscribe(Subscription), which is guaranteed to be called before any onNext. This keeps the API uniform for sync and async sources.
- Do you often implement Subscriber or Processor by hand in Spring apps?Rarely. You compose Reactor operators (map/filter/flatMap) and return Flux/Mono; Reactor implements the interfaces internally. You implement a raw Subscriber only for low-level custom sinks or interop, and Processor almost never — Sinks replaced the old Processor types.
saying these in an interview costs you the question
- Saying Publisher.subscribe returns the Subscription
- Confusing Subscription (control channel) with Subscriber (consumer)
- Claiming a Publisher starts emitting immediately without a subscriber
- Thinking Processor is a separate thing unrelated to Subscriber/Publisher