{"id":13621857,"url":"https://github.com/reactor/reactor-core","last_synced_at":"2026-04-14T08:02:53.481Z","repository":{"id":37412560,"uuid":"45903621","full_name":"reactor/reactor-core","owner":"reactor","description":"Non-Blocking Reactive Foundation for the JVM","archived":false,"fork":false,"pushed_at":"2025-05-13T10:11:43.000Z","size":65561,"stargazers_count":5082,"open_issues_count":51,"forks_count":1218,"subscribers_count":169,"default_branch":"main","last_synced_at":"2025-05-13T10:23:07.003Z","etag":null,"topics":["asynchronous","flow","flux","jvm","mono","reactive","reactive-extensions","reactive-streams"],"latest_commit_sha":null,"homepage":"http://projectreactor.io","language":"Java","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":"apache-2.0","status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/reactor.png","metadata":{"files":{"readme":"README.md","changelog":null,"contributing":null,"funding":null,"license":"LICENSE","code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":".github/CODEOWNERS","security":null,"support":null,"governance":null,"roadmap":null,"authors":null,"dei":null,"publiccode":null,"codemeta":null,"zenodo":null}},"created_at":"2015-11-10T10:06:40.000Z","updated_at":"2025-05-13T09:45:54.000Z","dependencies_parsed_at":"2023-10-02T07:42:49.529Z","dependency_job_id":"2c30258e-f8bf-4a91-9eb3-3af8d1730e77","html_url":"https://github.com/reactor/reactor-core","commit_stats":{"total_commits":3924,"total_committers":249,"mean_commits":"15.759036144578314","dds":0.6827217125382263,"last_synced_commit":"558f154ac00b2baa05280fdb36b98f40960bbc67"},"previous_names":[],"tags_count":202,"template":false,"template_full_name":null,"repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/reactor%2Freactor-core","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/reactor%2Freactor-core/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/reactor%2Freactor-core/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/reactor%2Freactor-core/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/reactor","download_url":"https://codeload.github.com/reactor/reactor-core/tar.gz/refs/heads/main","host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":253929320,"owners_count":21985800,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2022-07-04T15:15:14.044Z","host_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub","repositories_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories","repository_names_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repository_names","owners_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners"}},"keywords":["asynchronous","flow","flux","jvm","mono","reactive","reactive-extensions","reactive-streams"],"created_at":"2024-08-01T21:01:11.293Z","updated_at":"2026-04-14T08:02:53.475Z","avatar_url":"https://github.com/reactor.png","language":"Java","readme":"# Reactor Core\n\n[![Join the chat at https://gitter.im/reactor/reactor](https://badges.gitter.im/Join%20Chat.svg)](https://gitter.im/reactor/reactor?utm_source=badge\u0026utm_medium=badge\u0026utm_campaign=pr-badge\u0026utm_content=badge)\n[![Reactor Core](https://maven-badges.herokuapp.com/maven-central/io.projectreactor/reactor-core/badge.svg?style=plastic)](https://mvnrepository.com/artifact/io.projectreactor/reactor-core) [![Latest](https://img.shields.io/github/release/reactor/reactor-core/all.svg)]() \n\n[![CI on GHA](https://github.com/reactor/reactor-core/actions/workflows/publish.yml/badge.svg)](https://github.com/reactor/reactor-core/actions/workflows/publish.yml)\n[![CodeQL](https://github.com/reactor/reactor-core/actions/workflows/codeql-analysis.yml/badge.svg)](https://github.com/reactor/reactor-core/actions/workflows/codeql-analysis.yml)\n\nNon-Blocking [Reactive Streams](https://www.reactive-streams.org/) Foundation for the JVM both implementing a [Reactive Extensions](https://reactivex.io) inspired API and efficient event streaming support.\n\nSince `3.3.x`, this repository also contains `reactor-tools`, a java agent aimed at helping with debugging of Reactor code.\n\n## Getting it\n   \n**Reactor 3 requires Java 8 or + to run**.\n\nWith Gradle from repo.spring.io or Maven Central repositories (stable releases only):\n\n```groovy\nrepositories {\n    mavenCentral()\n\n    // Uncomment to get access to Snapshots\n    // maven { url \"https://repo.spring.io/snapshot\" }\n}\n\ndependencies {\n    compile \"io.projectreactor:reactor-core:3.8.5\"\n    testCompile \"io.projectreactor:reactor-test:3.8.5\"\n\n    // Alternatively, use the following for latest snapshot artifacts in this line\n    // compile \"io.projectreactor:reactor-core:3.8.6-SNAPSHOT\"\n    // testCompile \"io.projectreactor:reactor-test:3.8.6-SNAPSHOT\"\n\n    // Optionally, use `reactor-tools` to help debugging reactor code\n    // implementation \"io.projectreactor:reactor-tools:3.8.5\"\n}\n```\n\nSee the [reference documentation](https://projectreactor.io/docs/core/release/reference/docs/index.html#getting)\nfor more information on getting it (eg. using Maven, or on how to get milestones and snapshots).\n\n\u003e **Note about Android support**: Reactor 3 doesn't officially support nor target Android.\nHowever it should work fine with Android SDK 21 (Android 5.0) and above. See the\n[complete note](https://projectreactor.io/docs/core/release/reference/docs/index.html#prerequisites)\nin the reference guide.\n\n## Trouble building the project?\nSince the introduction of [Java Multi-Release JAR File](https://openjdk.org/jeps/238) \nsupport one needs to have JDK 8, 9, and 21 available on the classpath. All the JDKs should \nbe automatically [detected](https://docs.gradle.org/current/userguide/toolchains.html#sec:auto_detection) \nor [provisioned](https://docs.gradle.org/current/userguide/toolchains.html#sec:provisioning) \nby Gradle Toolchain. \n\nHowever, if you see error message such as `No matching toolchains found for requested \nspecification: {languageVersion=X, vendor=any, implementation=vendor-specific}` (where \n`X` can be 8, 9 or 21), it means that you need to install the missing JDK:\n\n### Installing JDKs with [SDKMAN!](https://sdkman.io/)\n\nIn the project root folder run [SDKMAN env initialization](https://sdkman.io/usage#env): \n\n```shell\nsdk env install\n```\n\nthen (if needed) install JDK 9: \n\n```shell\nsdk install java $(sdk list java | grep -Eo -m1 '9\\b\\.[ea|0-9]{1,2}\\.[0-9]{1,2}-open')\n```\n\nthen (if needed) install JDK 21:\n\n```shell\nsdk install java $(sdk list java | grep -Eo -m1 '21\\b\\.[ea|0-9]{1,2}\\.[0-9]{1,2}-open')\n```\n\nWhen the installations succeed, try to refresh the project and see that it builds.\n\n### Installing JDKs manually\n\nThe manual Operation-system specific JDK installation\nis well explained in the [official docs](https://docs.oracle.com/en/java/javase/20/install/overview-jdk-installation.html)\n\n### Building the doc\n\nThe current active shell JDK version must be compatible with JDK17 or higher for Antora to build successfully.\nSo, just ensure that you have installed JDK 21, as described above and make it as the current one. \n\nThen you can build the antora documentation like this:\n```shell\n./gradlew docs\n```\n\nThe documentation is generated in `docs/build/site/index.html` and in `docs/build/distributions/reactor-core-\u003cversion\u003e-docs.zip` \nIf a PDF file should also be included in the generated docs zip file, then you need to specify `-PforcePdf` option:\n\n```shell\n./gradlew docs -PforcePdf\n```\nNotice that PDF generation requires the `asciidoctor-pdf` command to be available in the PATH. \nFor example, on Mac OS, you can install such command like this:\n\n```shell\nbrew install asciidoctor\n```\n\n## Getting Started\n\nNew to Reactive Programming or bored of reading already ? Try the [Introduction to Reactor Core hands-on](https://github.com/reactor/lite-rx-api-hands-on) !\n\nIf you are familiar with RxJava or if you want to check more detailed introduction, be sure to check \nhttps://www.infoq.com/articles/reactor-by-example !\n\n## Flux\n\nA Reactive Streams Publisher with basic flow operators.\n- Static factories on Flux allow for source generation from arbitrary callbacks types.\n- Instance methods allows operational building, materialized on each subscription (_Flux#subscribe()_, ...) or multicasting operations (such as _Flux#publish_ and _Flux#publishNext_).\n\n[\u003cimg src=\"https://raw.githubusercontent.com/reactor/reactor-core/v3.1.3.RELEASE/src/docs/marble/flux.png\" width=\"500\" style=\"background-color: white\"\u003e](https://projectreactor.io/docs/core/release/api/reactor/core/publisher/Flux.html)\n\nFlux in action :\n```java\nFlux.fromIterable(getSomeLongList())\n    .mergeWith(Flux.interval(100))\n    .doOnNext(serviceA::someObserver)\n    .map(d -\u003e d * 2)\n    .take(3)\n    .onErrorResume(errorHandler::fallback)\n    .doAfterTerminate(serviceM::incrementTerminate)\n    .subscribe(System.out::println);\n```\n\n## Mono\nA Reactive Streams Publisher constrained to *ZERO* or *ONE* element with appropriate operators. \n- Static factories on Mono allow for deterministic *zero or one* sequence generation from arbitrary callbacks types.\n- Instance methods allows operational building, materialized on each _Mono#subscribe()_ or _Mono#get()_ eventually called.\n\n[\u003cimg src=\"https://raw.githubusercontent.com/reactor/reactor-core/v3.4.1/reactor-core/src/main/java/reactor/core/publisher/doc-files/marbles/mono.svg\" width=\"500\" style=\"background-color: white\"\u003e](https://projectreactor.io/docs/core/release/api/reactor/core/publisher/Mono.html)\n\nMono in action :\n```java\nMono.fromCallable(System::currentTimeMillis)\n    .flatMap(time -\u003e Mono.first(serviceA.findRecent(time), serviceB.findRecent(time)))\n    .timeout(Duration.ofSeconds(3), errorHandler::fallback)\n    .doOnSuccess(r -\u003e serviceM.incrementSuccess())\n    .subscribe(System.out::println);\n```\n\nBlocking Mono result :\n```java\nTuple2\u003cInstant, Instant\u003e nowAndLater = Mono.zip(\n    Mono.just(Instant.now()),\n    Mono.delay(Duration.ofSeconds(1)).then(Mono.fromCallable(Instant::now)))\n  .block();\n```\n\n## Schedulers\n\nReactor uses a [Scheduler](https://projectreactor.io/docs/core/release/api/reactor/core/scheduler/Scheduler.html) as a\ncontract for arbitrary task execution. It provides some guarantees required by Reactive\nStreams flows like FIFO execution.\n\nYou can use or create efficient [schedulers](https://projectreactor.io/docs/core/release/api/reactor/core/scheduler/Schedulers.html)\nto jump thread on the producing flows (subscribeOn) or receiving flows (publishOn):\n\n```java\n\nMono.fromCallable( () -\u003e System.currentTimeMillis() )\n\t.repeat()\n    .publishOn(Schedulers.single())\n    .log(\"foo.bar\")\n    .flatMap(time -\u003e\n        Mono.fromCallable(() -\u003e { Thread.sleep(1000); return time; })\n            .subscribeOn(Schedulers.parallel())\n    , 8) //maxConcurrency 8\n    .subscribe();\n```\n\n## ParallelFlux\n\n[ParallelFlux](https://projectreactor.io/docs/core/release/api/reactor/core/publisher/ParallelFlux.html) can starve your CPU's from any sequence whose work can be subdivided in concurrent\n tasks. Turn back into a `Flux` with `ParallelFlux#sequential()`, an unordered join or\n use arbitrary merge strategies via 'groups()'.\n\n```java\nMono.fromCallable( () -\u003e System.currentTimeMillis() )\n\t.repeat()\n    .parallel(8) //parallelism\n    .runOn(Schedulers.parallel())\n    .doOnNext( d -\u003e System.out.println(\"I'm on thread \"+Thread.currentThread()) )\n    .subscribe()\n```\n\n\n## Custom sources : Flux.create and FluxSink, Mono.create and MonoSink\nTo bridge a Subscriber or Processor into an outside context that is taking care of\nproducing non concurrently, use `Flux#create`, `Mono#create`.\n\n```java\nFlux.create(sink -\u003e {\n         ActionListener al = e -\u003e {\n            sink.next(textField.getText());\n         };\n\n         // without cancellation support:\n         button.addActionListener(al);\n\n         // with cancellation support:\n         sink.onCancel(() -\u003e {\n         \tbutton.removeListener(al);\n         });\n    },\n    // Overflow (backpressure) handling, default is BUFFER\n    FluxSink.OverflowStrategy.LATEST)\n    .timeout(Duration.ofSeconds(3))\n    .doOnComplete(() -\u003e System.out.println(\"completed!\"))\n    .subscribe(System.out::println)\n```\n\n## The Backpressure Thing\n\nMost 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](https://github.com/reactor/reactive-streams-commons) on going research effort.\n\n## What's more in it ?\n\n\"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`](https://projectreactor.io/docs/test/release/api/index.html?reactor/test/StepVerifier.html).\n\n-------------------------------------\n\n## Reference Guide\nhttps://projectreactor.io/docs/core/release/reference/docs/index.html\n\n## Javadoc\nhttps://projectreactor.io/docs/core/release/api/\n\n## Getting started with Flux and Mono\nhttps://github.com/reactor/lite-rx-api-hands-on\n\n## Reactor By Example\nhttps://www.infoq.com/articles/reactor-by-example\n\n## Head-First Spring \u0026 Reactor\nhttps://github.com/reactor/head-first-reactive-with-spring-and-reactor/\n\n## Beyond Reactor Core\n- Everything to jump outside the JVM with the non-blocking drivers from [Reactor Netty](https://github.com/reactor/reactor-netty).\n- [Reactor Addons](https://github.com/reactor/reactor-addons) provide for adapters and extra operators for Reactor 3.\n\n-------------------------------------\n_Powered by [Reactive Streams Commons](https://github.com/reactor/reactive-streams-commons)_\n\n_Licensed under [Apache Software License 2.0](https://www.apache.org/licenses/LICENSE-2.0)_\n\n_Sponsored by [VMware](https://tanzu.vmware.com/)_\n","funding_links":[],"categories":["Java","Projects","Stack","项目","并发编程","三、架构与框架（支撑大型应用）"],"sub_categories":["Reactive libraries","Reactive Stack","反应式库","5. 响应式编程（高并发场景）"],"project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Freactor%2Freactor-core","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Freactor%2Freactor-core","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Freactor%2Freactor-core/lists"}