diff --git a/spring-core/src/main/java/org/springframework/core/ReactiveAdapter.java b/spring-core/src/main/java/org/springframework/core/ReactiveAdapter.java
index a829562f2d..7737ba5d12 100644
--- a/spring-core/src/main/java/org/springframework/core/ReactiveAdapter.java
+++ b/spring-core/src/main/java/org/springframework/core/ReactiveAdapter.java
@@ -37,7 +37,7 @@ public interface ReactiveAdapter {
/**
* Return a descriptor with further information about the adaptee.
*/
- Descriptor getDescriptor();
+ ReactiveTypeDescriptor getDescriptor();
/**
* Adapt the given Object to a {@link Mono}
@@ -67,48 +67,4 @@ public interface ReactiveAdapter {
*/
Object fromPublisher(Publisher> publisher);
-
- /**
- * A descriptor with information about the adaptee stream semantics.
- */
- class Descriptor {
-
- private final boolean isMultiValue;
-
- private final boolean supportsEmpty;
-
- private final boolean isNoValue;
-
- public Descriptor(boolean isMultiValue, boolean canBeEmpty, boolean isNoValue) {
- this.isMultiValue = isMultiValue;
- this.supportsEmpty = canBeEmpty;
- this.isNoValue = isNoValue;
- }
-
- /**
- * Return {@code true} if the adaptee implies 0..N values can be produced
- * and is therefore a good fit to adapt to {@link Flux}. A {@code false}
- * return value implies the adaptee will produce 1 value at most and is
- * therefore a good fit for {@link Mono}.
- */
- public boolean isMultiValue() {
- return this.isMultiValue;
- }
-
- /**
- * Return {@code true} if the adaptee can complete without values.
- */
- public boolean supportsEmpty() {
- return this.supportsEmpty;
- }
-
- /**
- * Return {@code true} if the adaptee implies no values will be produced,
- * i.e. providing only completion or error signal.
- */
- public boolean isNoValue() {
- return this.isNoValue;
- }
- }
-
}
diff --git a/spring-core/src/main/java/org/springframework/core/ReactiveAdapterRegistry.java b/spring-core/src/main/java/org/springframework/core/ReactiveAdapterRegistry.java
index 6be6025637..f30d9d4485 100644
--- a/spring-core/src/main/java/org/springframework/core/ReactiveAdapterRegistry.java
+++ b/spring-core/src/main/java/org/springframework/core/ReactiveAdapterRegistry.java
@@ -16,8 +16,8 @@
package org.springframework.core;
-import java.util.LinkedHashMap;
-import java.util.Map;
+import java.util.ArrayList;
+import java.util.List;
import java.util.Optional;
import java.util.concurrent.CompletableFuture;
import java.util.function.Function;
@@ -29,19 +29,17 @@ import io.reactivex.Maybe;
import org.reactivestreams.Publisher;
import reactor.core.publisher.Flux;
import reactor.core.publisher.Mono;
-import rx.Completable;
-import rx.Observable;
import rx.RxReactiveStreams;
-import rx.Single;
import org.springframework.util.ClassUtils;
/**
* A registry of adapters to adapt to {@link Flux} and {@link Mono}.
*
- *
By default there are adapters for {@link CompletableFuture}, RxJava 1, and
- * also for a any Reactive Streams {@link Publisher}. Additional adapters can be
- * registered via {@link #registerFluxAdapter} and {@link #registerMonoAdapter}.
+ *
By default, depending on classpath availability, adapters are registered
+ * for RxJava 1, RxJava 2 types, and {@link CompletableFuture}. In addition the
+ * registry contains adapters for Reactor's own Flux and Mono types (no-op)
+ * along with adaption for any other Reactive Streams {@link Publisher}.
*
* @author Rossen Stoyanchev
* @author Sebastien Deleuze
@@ -58,25 +56,30 @@ public class ReactiveAdapterRegistry {
private static final boolean rxJava2Present =
ClassUtils.isPresent("io.reactivex.Flowable", ReactiveAdapterRegistry.class.getClassLoader());
- private final Map, ReactiveAdapter> adapterMap = new LinkedHashMap<>(4);
+
+ private final List adapters = new ArrayList<>(32);
/**
* Create a registry and auto-register default adapters.
*/
public ReactiveAdapterRegistry() {
+
// Flux and Mono ahead of Publisher...
+
registerMonoAdapter(Mono.class,
source -> (Mono>) source, source -> source,
- new ReactiveAdapter.Descriptor(false, true, false));
- registerFluxAdapter(
- Flux.class, source -> (Flux>) source, source -> source);
- registerFluxAdapter(
- Publisher.class, source -> Flux.from((Publisher>) source), source -> source);
+ ReactiveTypeDescriptor.singleOptionalValue(Mono.class));
+
+ registerFluxAdapter(Flux.class,
+ source -> (Flux>) source, source -> source);
+
+ registerFluxAdapter(Publisher.class,
+ source -> Flux.from((Publisher>) source), source -> source);
registerMonoAdapter(CompletableFuture.class,
source -> Mono.fromFuture((CompletableFuture>) source), Mono::toFuture,
- new ReactiveAdapter.Descriptor(false, true, false)
+ ReactiveTypeDescriptor.singleOptionalValue(CompletableFuture.class)
);
if (rxJava1Present && rxJava1Adapter) {
@@ -93,10 +96,10 @@ public class ReactiveAdapterRegistry {
*
The provided functions can assume that input will never be {@code null}
* and also that any {@link Optional} wrapper is unwrapped.
*/
- public void registerMonoAdapter(Class> adapteeType, Function