Convert Figma logo to code with AI

reactor logoreactor-core

Non-Blocking Reactive Foundation for the JVM

4,952
1,199
4,952
57

Top Related Projects

Spring Framework

13,047

Build highly concurrent, distributed, and resilient message-driven applications on the JVM

47,869

RxJava – Reactive Extensions for the JVM – a library for composing asynchronous and event-based programs using observable sequences for the Java VM.

14,281

Vert.x is a tool-kit for building reactive applications on the JVM

30,713

A reactive programming library for JavaScript

The Reactive Extensions for .NET

Quick Overview

Reactor Core is a reactive library for building non-blocking applications on the JVM. It provides efficient demand management and is the foundation for the Spring WebFlux module. Reactor Core implements the Reactive Streams specification and offers powerful operators for composing asynchronous sequences.

Pros

  • Non-blocking and backpressure-ready, allowing for efficient resource management
  • Extensive operator set for complex stream manipulations
  • Integrates well with Spring ecosystem, especially Spring WebFlux
  • Supports both Java and Kotlin with idiomatic APIs

Cons

  • Steep learning curve for developers new to reactive programming
  • Debugging can be challenging due to the asynchronous nature of operations
  • May introduce unnecessary complexity for simple, synchronous use cases
  • Performance benefits may not be significant for low-concurrency scenarios

Code Examples

Creating a simple Flux:

Flux<String> flux = Flux.just("Hello", "World");
flux.subscribe(System.out::println);

Transforming a Flux using operators:

Flux.range(1, 5)
    .map(i -> i * 2)
    .filter(i -> i > 5)
    .subscribe(System.out::println);

Handling errors in a reactive stream:

Flux.just(1, 2, 0)
    .map(i -> 10 / i)
    .onErrorReturn(-1)
    .subscribe(System.out::println);

Getting Started

To use Reactor Core in your project, add the following dependency to your Maven pom.xml:

<dependency>
    <groupId>io.projectreactor</groupId>
    <artifactId>reactor-core</artifactId>
    <version>3.5.6</version>
</dependency>

Or for Gradle, add this to your build.gradle:

implementation 'io.projectreactor:reactor-core:3.5.6'

Then, you can start using Reactor in your Java code:

import reactor.core.publisher.Flux;

public class ReactorExample {
    public static void main(String[] args) {
        Flux<Integer> numbers = Flux.range(1, 5);
        numbers.subscribe(System.out::println);
    }
}

This example creates a simple Flux of integers and subscribes to it, printing each number to the console.

Competitor Comparisons

Spring Framework

Pros of Spring Framework

  • Comprehensive ecosystem with extensive features for web development, security, and data access
  • Large community and extensive documentation, making it easier to find solutions and support
  • Mature and battle-tested framework with a long history of enterprise-level usage

Cons of Spring Framework

  • Steeper learning curve due to its vast feature set and complexity
  • Can be considered "heavyweight" for smaller projects or microservices
  • Slower startup times compared to more lightweight frameworks

Code Comparison

Spring Framework (Dependency Injection):

@Service
public class UserService {
    @Autowired
    private UserRepository userRepository;
}

Reactor Core (Reactive Programming):

Flux<User> users = Flux.fromIterable(userList)
    .filter(user -> user.getAge() > 18)
    .map(User::getName);

Spring Framework focuses on dependency injection and inversion of control, while Reactor Core emphasizes reactive programming patterns. Spring Framework provides a full-featured application framework, whereas Reactor Core is specifically designed for building reactive applications with non-blocking back pressure support.

13,047

Build highly concurrent, distributed, and resilient message-driven applications on the JVM

Pros of Akka

  • More comprehensive actor-based concurrency model
  • Supports distributed systems and clustering out-of-the-box
  • Offers a wider range of features beyond reactive streams

Cons of Akka

  • Steeper learning curve due to its broader scope
  • Heavier runtime footprint compared to Reactor Core
  • Less focused on pure reactive programming concepts

Code Comparison

Akka (Actor-based):

class MyActor extends Actor {
  def receive = {
    case "hello" => println("Hello, world!")
    case _       => println("Unknown message")
  }
}

Reactor Core (Reactive Streams):

Flux.just("hello")
    .map(String::toUpperCase)
    .subscribe(System.out::println);

Akka focuses on actor-based concurrency, while Reactor Core emphasizes reactive streams. Akka's code style is more object-oriented, with actors handling messages, whereas Reactor Core uses a functional approach with operators chained together.

Akka provides a full-fledged toolkit for building distributed systems, including features like clustering and persistence. Reactor Core, on the other hand, is more lightweight and specifically designed for reactive programming in non-distributed environments.

Choose Akka for complex, distributed systems with diverse concurrency needs. Opt for Reactor Core when focusing on reactive programming in a single JVM with a smaller footprint.

47,869

RxJava – Reactive Extensions for the JVM – a library for composing asynchronous and event-based programs using observable sequences for the Java VM.

Pros of RxJava

  • Larger ecosystem with more operators and extensions
  • Better support for Android development
  • More mature project with a longer history and larger community

Cons of RxJava

  • Steeper learning curve due to more complex API
  • Higher memory footprint and potential performance overhead
  • Less integrated with modern Java features (e.g., Flow API)

Code Comparison

RxJava:

Observable.just(1, 2, 3)
    .map(i -> i * 2)
    .subscribe(System.out::println);

Reactor Core:

Flux.just(1, 2, 3)
    .map(i -> i * 2)
    .subscribe(System.out::println);

Both libraries provide similar functionality for creating and manipulating reactive streams. The main differences lie in naming conventions and specific operator implementations. RxJava uses Observable as its primary type, while Reactor Core uses Flux for multi-element streams and Mono for single-element streams.

Reactor Core is more focused on the Reactive Streams specification and integrates better with Spring ecosystem. It has a smaller API surface, which can make it easier to learn and use. However, RxJava's larger ecosystem and longer history mean it has more third-party libraries and resources available.

Choose RxJava for Android development or if you need a wide range of operators. Opt for Reactor Core if you're working with Spring or prefer a more streamlined API that closely follows Reactive Streams specifications.

14,281

Vert.x is a tool-kit for building reactive applications on the JVM

Pros of Vert.x

  • More comprehensive toolkit for building reactive applications, including HTTP server/client, database access, and more
  • Polyglot nature supports multiple programming languages (Java, JavaScript, Groovy, etc.)
  • Built-in clustering and high availability features

Cons of Vert.x

  • Steeper learning curve due to its broader scope and more complex architecture
  • Potentially heavier resource usage for simpler applications
  • Less focus on pure reactive programming concepts compared to Reactor Core

Code Comparison

Vert.x example:

Vertx vertx = Vertx.vertx();
vertx.createHttpServer()
    .requestHandler(req -> req.response().end("Hello World!"))
    .listen(8080);

Reactor Core example:

Flux.just("Hello", "World")
    .map(String::toUpperCase)
    .subscribe(System.out::println);

While both libraries support reactive programming, Vert.x provides a more comprehensive toolkit for building full-stack applications, whereas Reactor Core focuses on reactive streams and operators. Vert.x's example shows HTTP server creation, while Reactor Core's example demonstrates basic stream processing. The choice between them depends on the specific requirements of your project and the desired level of abstraction.

30,713

A reactive programming library for JavaScript

Pros of RxJS

  • Wider ecosystem and community support
  • More extensive operator library
  • Better integration with Angular framework

Cons of RxJS

  • Steeper learning curve
  • Larger bundle size
  • Less focus on backpressure handling

Code Comparison

RxJS:

import { of } from 'rxjs';
import { map, filter } from 'rxjs/operators';

of(1, 2, 3, 4, 5)
  .pipe(
    filter(n => n % 2 === 0),
    map(n => n * 2)
  )
  .subscribe(console.log);

Reactor Core:

import reactor.core.publisher.Flux;

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

Both libraries provide similar functionality for reactive programming, but RxJS is more popular in the JavaScript ecosystem, especially for frontend development. Reactor Core is primarily used in Java applications, particularly with Spring WebFlux. RxJS offers a richer set of operators and better integration with Angular, while Reactor Core excels in handling backpressure and is more lightweight. The code syntax is similar, with minor differences in method names and chaining style.

The Reactive Extensions for .NET

Pros of Reactive

  • Tighter integration with .NET ecosystem and languages (C#, F#, VB.NET)
  • More extensive documentation and learning resources
  • Broader support for various .NET platforms (Framework, Core, Standard)

Cons of Reactive

  • Smaller community compared to Reactor Core
  • Less frequent updates and releases
  • Limited support for non-.NET languages

Code Comparison

Reactor Core (Java):

Flux.range(1, 5)
    .map(i -> i * 2)
    .subscribe(System.out::println);

Reactive (C#):

Observable.Range(1, 5)
    .Select(i => i * 2)
    .Subscribe(Console.WriteLine);

Both libraries provide similar functionality for creating and manipulating reactive streams. Reactor Core uses Flux and Mono as primary types, while Reactive uses IObservable<T>. The syntax is slightly different due to language differences, but the concepts remain similar.

Reactor Core tends to have more specialized operators and a more extensive API, while Reactive focuses on providing core reactive programming capabilities within the .NET ecosystem. The choice between the two often depends on the target platform and language preferences of the development team.

Convert Figma logo designs to code with AI

Visual Copilot

Introducing Visual Copilot: A new AI model to turn Figma designs to high quality code using your components.

Try Visual Copilot

README

Reactor Core

Join the chat at https://gitter.im/reactor/reactor Reactor Core Latest

CI on GHA Codecov Code Quality: Java Total Alerts

Non-Blocking Reactive Streams Foundation for the JVM both implementing a Reactive Extensions inspired API and efficient event streaming support.

Since 3.3.x, this repository also contains reactor-tools, a java agent aimed at helping with debugging of Reactor code.

Getting it

Reactor 3 requires Java 8 or + to run.

With Gradle from repo.spring.io or Maven Central repositories (stable releases only):

repositories {
    mavenCentral()

    // Uncomment to get access to Milestones
    // maven { url "https://repo.spring.io/milestone" }

    // Uncomment to get access to Snapshots
    // maven { url "https://repo.spring.io/snapshot" }
}

dependencies {
    compile "io.projectreactor:reactor-core:3.7.0-M6"
    testCompile "io.projectreactor:reactor-test:3.7.0-M6"

    // Alternatively, use the following for latest snapshot artifacts in this line
    // compile "io.projectreactor:reactor-core:3.7.0-SNAPSHOT"
    // testCompile "io.projectreactor:reactor-test:3.7.0-SNAPSHOT"

    // Optionally, use `reactor-tools` to help debugging reactor code
    // implementation "io.projectreactor:reactor-tools:3.7.0-M6"
}

See the reference documentation for more information on getting it (eg. using Maven, or on how to get milestones and snapshots).

Note about Android support: Reactor 3 doesn't officially support nor target Android. However it should work fine with Android SDK 21 (Android 5.0) and above. See the complete note in the reference guide.

Trouble building the project?

Since the introduction of Java Multi-Release JAR File support one needs to have JDK 8, 9, and 21 available on the classpath. All the JDKs should be automatically detected or provisioned by Gradle Toolchain.

However, if you see error message such as No matching toolchains found for requested specification: {languageVersion=X, vendor=any, implementation=vendor-specific} (where X can be 8, 9 or 21), it means that you need to install the missing JDK:

Installing JDKs with SDKMAN!

In the project root folder run SDKMAN env initialization:

sdk env install

then (if needed) install JDK 9:

sdk install java $(sdk list java | grep -Eo -m1 '9\b\.[ea|0-9]{1,2}\.[0-9]{1,2}-open')

then (if needed) install JDK 21:

sdk install java $(sdk list java | grep -Eo -m1 '21\b\.[ea|0-9]{1,2}\.[0-9]{1,2}-open')

When the installations succeed, try to refresh the project and see that it builds.

Installing JDKs manually

The manual Operation-system specific JDK installation is well explained in the official docs

Building the doc

The current active shell JDK version must be compatible with JDK17 or higher for Antora to build successfully. So, just ensure that you have installed JDK 21, as described above and make it as the current one.

Then you can build the antora documentation like this:

./gradlew docs

The documentation is generated in docs/build/site/index.html and in docs/build/distributions/reactor-core-<version>-docs.zip If a PDF file should also be included in the generated docs zip file, then you need to specify -PforcePdf option:

./gradlew docs -PforcePdf

Notice that PDF generation requires the asciidoctor-pdf command to be available in the PATH. For example, on Mac OS, you can install such command like this:

brew install asciidoctor

Getting Started

New to Reactive Programming or bored of reading already ? Try the Introduction to Reactor Core hands-on !

If you are familiar with RxJava or if you want to check more detailed introduction, be sure to check https://www.infoq.com/articles/reactor-by-example !

Flux

A Reactive Streams Publisher with basic flow operators.

  • Static factories on Flux allow for source generation from arbitrary callbacks types.
  • Instance methods allows operational building, materialized on each subscription (Flux#subscribe(), ...) or multicasting operations (such as Flux#publish and Flux#publishNext).

Flux in action :

Flux.fromIterable(getSomeLongList())
    .mergeWith(Flux.interval(100))
    .doOnNext(serviceA::someObserver)
    .map(d -> d * 2)
    .take(3)
    .onErrorResume(errorHandler::fallback)
    .doAfterTerminate(serviceM::incrementTerminate)
    .subscribe(System.out::println);

Mono

A Reactive Streams Publisher constrained to ZERO or ONE element with appropriate operators.

  • Static factories on Mono allow for deterministic zero or one sequence generation from arbitrary callbacks types.
  • Instance methods allows operational building, materialized on each Mono#subscribe() or Mono#get() eventually called.

Mono in action :

Mono.fromCallable(System::currentTimeMillis)
    .flatMap(time -> Mono.first(serviceA.findRecent(time), serviceB.findRecent(time)))
    .timeout(Duration.ofSeconds(3), errorHandler::fallback)
    .doOnSuccess(r -> serviceM.incrementSuccess())
    .subscribe(System.out::println);

Blocking Mono result :

Tuple2<Instant, Instant> nowAndLater = Mono.zip(
    Mono.just(Instant.now()),
    Mono.delay(Duration.ofSeconds(1)).then(Mono.fromCallable(Instant::now)))
  .block();

Schedulers

Reactor uses a Scheduler as a contract for arbitrary task execution. It provides some guarantees required by Reactive Streams flows like FIFO execution.

You can use or create efficient schedulers to jump thread on the producing flows (subscribeOn) or receiving flows (publishOn):


Mono.fromCallable( () -> System.currentTimeMillis() )
	.repeat()
    .publishOn(Schedulers.single())
    .log("foo.bar")
    .flatMap(time ->
        Mono.fromCallable(() -> { Thread.sleep(1000); return time; })
            .subscribeOn(Schedulers.parallel())
    , 8) //maxConcurrency 8
    .subscribe();

ParallelFlux

ParallelFlux can starve your CPU's from any sequence whose work can be subdivided in concurrent tasks. Turn back into a Flux with ParallelFlux#sequential(), an unordered join or use arbitrary merge strategies via 'groups()'.

Mono.fromCallable( () -> System.currentTimeMillis() )
	.repeat()
    .parallel(8) //parallelism
    .runOn(Schedulers.parallel())
    .doOnNext( d -> System.out.println("I'm on thread "+Thread.currentThread()) )
    .subscribe()

Custom sources : Flux.create and FluxSink, Mono.create and MonoSink

To bridge a Subscriber or Processor into an outside context that is taking care of producing non concurrently, use Flux#create, Mono#create.

Flux.create(sink -> {
         ActionListener al = e -> {
            sink.next(textField.getText());
         };

         // without cancellation support:
         button.addActionListener(al);

         // with cancellation support:
         sink.onCancel(() -> {
         	button.removeListener(al);
         });
    },
    // Overflow (backpressure) handling, default is BUFFER
    FluxSink.OverflowStrategy.LATEST)
    .timeout(Duration.ofSeconds(3))
    .doOnComplete(() -> System.out.println("completed!"))
    .subscribe(System.out::println)

The Backpressure Thing

Most of this cool stuff uses bounded ring buffer implementation under the hood to mitigate signal processing difference between producers and consumers. Now, the operators and processors or any standard reactive stream component working on the sequence will be instructed to flow in when these buffers have free room AND only then. This means that we make sure we both have a deterministic capacity model (bounded buffer) and we never block (request more data on write capacity). Yup, it's not rocket science after all, the boring part is already being worked by us in collaboration with Reactive Streams Commons on going research effort.

What's more in it ?

"Operator Fusion" (flow optimizers), health state observers, helpers to build custom reactive components, bounded queue generator, converters from/to Java 9 Flow, Publisher and Java 8 CompletableFuture. The repository contains a reactor-test project with test features like the StepVerifier.


Reference Guide

https://projectreactor.io/docs/core/release/reference/docs/index.html

Javadoc

https://projectreactor.io/docs/core/release/api/

Getting started with Flux and Mono

https://github.com/reactor/lite-rx-api-hands-on

Reactor By Example

https://www.infoq.com/articles/reactor-by-example

Head-First Spring & Reactor

https://github.com/reactor/head-first-reactive-with-spring-and-reactor/

Beyond Reactor Core

  • Everything to jump outside the JVM with the non-blocking drivers from Reactor Netty.
  • Reactor Addons provide for adapters and extra operators for Reactor 3.

Powered by Reactive Streams Commons

Licensed under Apache Software License 2.0

Sponsored by VMware