From 5651c2180e7b19d0f53d65a8546b65910677f4fd Mon Sep 17 00:00:00 2001 From: Rossen Stoyanchev Date: Mon, 28 Nov 2016 12:43:22 -0500 Subject: [PATCH] Further refactoring of ReactiveAdapter/Registry Simplify getAdapterFrom/To into a single getAdapter method that looks for an exact match by type first and then isAssignableFrom. Also expose shortcut methods in ReactiveAdapter to minimize the need for access to the ReactiveTypeDescriptor. Issue: SPR-14902 --- .../springframework/core/ReactiveAdapter.java | 29 ++++++ .../core/ReactiveAdapterRegistry.java | 36 ++++--- .../support/ReactiveAdapterRegistryTests.java | 96 ++++++++++++------- ...AbstractMessageReaderArgumentResolver.java | 6 +- .../AbstractMessageWriterResultHandler.java | 10 +- .../annotation/BindingContextFactory.java | 2 +- .../ErrorsMethodArgumentResolver.java | 4 +- .../ModelAttributeMethodArgumentResolver.java | 18 ++-- .../annotation/ResponseBodyResultHandler.java | 5 +- .../ResponseEntityResultHandler.java | 13 +-- .../view/ViewResolutionResultHandler.java | 16 ++-- 11 files changed, 136 insertions(+), 99 deletions(-) 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 d856aa1602..5c8752da4e 100644 --- a/spring-core/src/main/java/org/springframework/core/ReactiveAdapter.java +++ b/spring-core/src/main/java/org/springframework/core/ReactiveAdapter.java @@ -70,6 +70,35 @@ public class ReactiveAdapter { return this.descriptor; } + /** + * A shortcut for {@code getDescriptor().getReactiveType()}. + */ + public Class getReactiveType() { + return getDescriptor().getReactiveType(); + } + + /** + * A shortcut for {@code getDescriptor().isMultiValue()}. + */ + public boolean isMultiValue() { + return getDescriptor().isMultiValue(); + } + + /** + * A shortcut for {@code getDescriptor().supportsEmpty()}. + */ + public boolean supportsEmpty() { + return getDescriptor().supportsEmpty(); + } + + /** + * A shortcut for {@code getDescriptor().isNoValue()}. + */ + public boolean isNoValue() { + return getDescriptor().isNoValue(); + } + + /** * Adapt the given instance to a Reactive Streams Publisher. * @param source the source object to adapt from 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 5cf10f1618..37145b006e 100644 --- a/spring-core/src/main/java/org/springframework/core/ReactiveAdapterRegistry.java +++ b/spring-core/src/main/java/org/springframework/core/ReactiveAdapterRegistry.java @@ -21,7 +21,6 @@ import java.util.List; import java.util.Optional; import java.util.concurrent.CompletableFuture; import java.util.function.Function; -import java.util.function.Predicate; import io.reactivex.BackpressureStrategy; import io.reactivex.Completable; @@ -101,34 +100,31 @@ public class ReactiveAdapterRegistry { } /** - * Get the adapter to use to adapt from the given reactive type. + * Get the adapter for the given reactive type. */ - public ReactiveAdapter getAdapterFrom(Class reactiveType) { - return getAdapterFrom(reactiveType, null); + public ReactiveAdapter getAdapter(Class reactiveType) { + return getAdapter(reactiveType, null); } /** - * Get the adapter to use to adapt from the given reactive type. Or if the - * "source" object is not {@code null} its actual type is used instead. + * Get the adapter for the given reactive type. Or if a "source" object is + * provided, its actual type is used instead. + * @param reactiveType the reactive type + * @param source an instance of the reactive type (i.e. to adapt from) */ - public ReactiveAdapter getAdapterFrom(Class reactiveType, Object source) { + public ReactiveAdapter getAdapter(Class reactiveType, Object source) { + source = (source instanceof Optional ? ((Optional) source).orElse(null) : source); Class clazz = (source != null ? source.getClass() : reactiveType); - return getAdapter(type -> type.isAssignableFrom(clazz)); - } - - /** - * Get the adapter for the given reactive type to adapt to. - */ - public ReactiveAdapter getAdapterTo(Class reactiveType) { - return getAdapter(reactiveType::equals); - } - private ReactiveAdapter getAdapter(Predicate> predicate) { return this.adapters.stream() - .filter(adapter -> predicate.test(adapter.getDescriptor().getReactiveType())) + .filter(adapter -> adapter.getReactiveType().equals(clazz)) .findFirst() - .orElse(null); + .orElseGet(() -> + this.adapters.stream() + .filter(adapter -> adapter.getReactiveType().isAssignableFrom(clazz)) + .findFirst() + .orElse(null)); } @@ -233,7 +229,7 @@ public class ReactiveAdapterRegistry { @Override public Publisher toPublisher(Object source) { Publisher publisher = super.toPublisher(source); - return (getDescriptor().isMultiValue() ? Flux.from(publisher) : Mono.from(publisher)); + return (isMultiValue() ? Flux.from(publisher) : Mono.from(publisher)); } } diff --git a/spring-core/src/test/java/org/springframework/core/convert/support/ReactiveAdapterRegistryTests.java b/spring-core/src/test/java/org/springframework/core/convert/support/ReactiveAdapterRegistryTests.java index 6be82a63a1..1271c34392 100644 --- a/spring-core/src/test/java/org/springframework/core/convert/support/ReactiveAdapterRegistryTests.java +++ b/spring-core/src/test/java/org/springframework/core/convert/support/ReactiveAdapterRegistryTests.java @@ -25,6 +25,7 @@ import org.junit.Before; import org.junit.Test; import org.reactivestreams.Publisher; import reactor.core.publisher.Flux; +import reactor.core.publisher.FluxProcessor; import reactor.core.publisher.Mono; import rx.Completable; import rx.Observable; @@ -32,10 +33,13 @@ import rx.Single; import org.springframework.core.ReactiveAdapter; import org.springframework.core.ReactiveAdapterRegistry; +import org.springframework.core.ReactiveTypeDescriptor; import static org.junit.Assert.assertEquals; import static org.junit.Assert.assertNotNull; +import static org.junit.Assert.assertNotSame; import static org.junit.Assert.assertNull; +import static org.junit.Assert.assertSame; import static org.junit.Assert.assertTrue; /** @@ -55,33 +59,55 @@ public class ReactiveAdapterRegistryTests { @Test - public void getDefaultAdapters() throws Exception { + public void defaultAdapterRegistrations() throws Exception { // Reactor - assertNotNull(getAdapterTo(Mono.class)); - assertNotNull(getAdapterTo(Flux.class)); + assertNotNull(getAdapter(Mono.class)); + assertNotNull(getAdapter(Flux.class)); - assertNotNull(getAdapterTo(Publisher.class)); - assertNotNull(getAdapterTo(CompletableFuture.class)); + // Publisher + assertNotNull(getAdapter(Publisher.class)); + + // Completable + assertNotNull(getAdapter(CompletableFuture.class)); // RxJava 1 - assertNotNull(getAdapterTo(Observable.class)); - assertNotNull(getAdapterTo(Single.class)); - assertNotNull(getAdapterTo(Completable.class)); + assertNotNull(getAdapter(Observable.class)); + assertNotNull(getAdapter(Single.class)); + assertNotNull(getAdapter(Completable.class)); // RxJava 2 - assertNotNull(getAdapterTo(Flowable.class)); - assertNotNull(getAdapterTo(io.reactivex.Observable.class)); - assertNotNull(getAdapterTo(io.reactivex.Single.class)); - assertNotNull(getAdapterTo(Maybe.class)); - assertNotNull(getAdapterTo(io.reactivex.Completable.class)); + assertNotNull(getAdapter(Flowable.class)); + assertNotNull(getAdapter(io.reactivex.Observable.class)); + assertNotNull(getAdapter(io.reactivex.Single.class)); + assertNotNull(getAdapter(Maybe.class)); + assertNotNull(getAdapter(io.reactivex.Completable.class)); + } + + @Test + public void getAdapterForReactiveSubType() throws Exception { + + ReactiveAdapter adapter1 = getAdapter(Flux.class); + ReactiveAdapter adapter2 = getAdapter(FluxProcessor.class); + + assertSame(adapter1, adapter2); + + this.registry.registerReactiveType( + ReactiveTypeDescriptor.multiValue(FluxProcessor.class, FluxProcessor::empty), + o -> (FluxProcessor) o, + FluxProcessor::from); + + ReactiveAdapter adapter3 = getAdapter(FluxProcessor.class); + + assertNotNull(adapter3); + assertNotSame(adapter1, adapter3); } @Test public void publisherToFlux() throws Exception { List sequence = Arrays.asList(1, 2, 3); Publisher source = Flowable.fromIterable(sequence); - Object target = getAdapterTo(Flux.class).fromPublisher(source); + Object target = getAdapter(Flux.class).fromPublisher(source); assertTrue(target instanceof Flux); assertEquals(sequence, ((Flux) target).collectList().blockMillis(1000)); } @@ -91,7 +117,7 @@ public class ReactiveAdapterRegistryTests { @Test public void publisherToMono() throws Exception { Publisher source = Flowable.fromArray(1, 2, 3); - Object target = getAdapterTo(Mono.class).fromPublisher(source); + Object target = getAdapter(Mono.class).fromPublisher(source); assertTrue(target instanceof Mono); assertEquals(new Integer(1), ((Mono) target).blockMillis(1000)); } @@ -99,7 +125,7 @@ public class ReactiveAdapterRegistryTests { @Test public void publisherToCompletableFuture() throws Exception { Publisher source = Flowable.fromArray(1, 2, 3); - Object target = getAdapterTo(CompletableFuture.class).fromPublisher(source); + Object target = getAdapter(CompletableFuture.class).fromPublisher(source); assertTrue(target instanceof CompletableFuture); assertEquals(new Integer(1), ((CompletableFuture) target).get()); } @@ -108,7 +134,7 @@ public class ReactiveAdapterRegistryTests { public void publisherToRxObservable() throws Exception { List sequence = Arrays.asList(1, 2, 3); Publisher source = Flowable.fromIterable(sequence); - Object target = getAdapterTo(rx.Observable.class).fromPublisher(source); + Object target = getAdapter(rx.Observable.class).fromPublisher(source); assertTrue(target instanceof rx.Observable); assertEquals(sequence, ((rx.Observable) target).toList().toBlocking().first()); } @@ -116,7 +142,7 @@ public class ReactiveAdapterRegistryTests { @Test public void publisherToRxSingle() throws Exception { Publisher source = Flowable.fromArray(1); - Object target = getAdapterTo(rx.Single.class).fromPublisher(source); + Object target = getAdapter(rx.Single.class).fromPublisher(source); assertTrue(target instanceof rx.Single); assertEquals(new Integer(1), ((rx.Single) target).toBlocking().value()); } @@ -124,7 +150,7 @@ public class ReactiveAdapterRegistryTests { @Test public void publisherToRxCompletable() throws Exception { Publisher source = Flowable.fromArray(1, 2, 3); - Object target = getAdapterTo(rx.Completable.class).fromPublisher(source); + Object target = getAdapter(rx.Completable.class).fromPublisher(source); assertTrue(target instanceof rx.Completable); assertNull(((rx.Completable) target).get()); } @@ -133,7 +159,7 @@ public class ReactiveAdapterRegistryTests { public void publisherToReactivexFlowable() throws Exception { List sequence = Arrays.asList(1, 2, 3); Publisher source = Flux.fromIterable(sequence); - Object target = getAdapterTo(io.reactivex.Flowable.class).fromPublisher(source); + Object target = getAdapter(io.reactivex.Flowable.class).fromPublisher(source); assertTrue(target instanceof io.reactivex.Flowable); assertEquals(sequence, ((io.reactivex.Flowable) target).toList().blockingGet()); } @@ -142,7 +168,7 @@ public class ReactiveAdapterRegistryTests { public void publisherToReactivexObservable() throws Exception { List sequence = Arrays.asList(1, 2, 3); Publisher source = Flowable.fromIterable(sequence); - Object target = getAdapterTo(io.reactivex.Observable.class).fromPublisher(source); + Object target = getAdapter(io.reactivex.Observable.class).fromPublisher(source); assertTrue(target instanceof io.reactivex.Observable); assertEquals(sequence, ((io.reactivex.Observable) target).toList().blockingGet()); } @@ -150,7 +176,7 @@ public class ReactiveAdapterRegistryTests { @Test public void publisherToReactivexSingle() throws Exception { Publisher source = Flowable.fromArray(1); - Object target = getAdapterTo(io.reactivex.Single.class).fromPublisher(source); + Object target = getAdapter(io.reactivex.Single.class).fromPublisher(source); assertTrue(target instanceof io.reactivex.Single); assertEquals(new Integer(1), ((io.reactivex.Single) target).blockingGet()); } @@ -158,7 +184,7 @@ public class ReactiveAdapterRegistryTests { @Test public void publisherToReactivexCompletable() throws Exception { Publisher source = Flowable.fromArray(1, 2, 3); - Object target = getAdapterTo(io.reactivex.Completable.class).fromPublisher(source); + Object target = getAdapter(io.reactivex.Completable.class).fromPublisher(source); assertTrue(target instanceof io.reactivex.Completable); assertNull(((io.reactivex.Completable) target).blockingGet()); } @@ -167,7 +193,7 @@ public class ReactiveAdapterRegistryTests { public void rxObservableToPublisher() throws Exception { List sequence = Arrays.asList(1, 2, 3); Object source = rx.Observable.from(sequence); - Object target = getAdapterFrom(rx.Observable.class).toPublisher(source); + Object target = getAdapter(rx.Observable.class).toPublisher(source); assertTrue("Expected Flux Publisher: " + target.getClass().getName(), target instanceof Flux); assertEquals(sequence, ((Flux) target).collectList().blockMillis(1000)); } @@ -175,7 +201,7 @@ public class ReactiveAdapterRegistryTests { @Test public void rxSingleToPublisher() throws Exception { Object source = rx.Single.just(1); - Object target = getAdapterFrom(rx.Single.class).toPublisher(source); + Object target = getAdapter(rx.Single.class).toPublisher(source); assertTrue("Expected Mono Publisher: " + target.getClass().getName(), target instanceof Mono); assertEquals(new Integer(1), ((Mono) target).blockMillis(1000)); } @@ -183,7 +209,7 @@ public class ReactiveAdapterRegistryTests { @Test public void rxCompletableToPublisher() throws Exception { Object source = rx.Completable.complete(); - Object target = getAdapterFrom(rx.Completable.class).toPublisher(source); + Object target = getAdapter(rx.Completable.class).toPublisher(source); assertTrue("Expected Mono Publisher: " + target.getClass().getName(), target instanceof Mono); ((Mono) target).blockMillis(1000); } @@ -192,7 +218,7 @@ public class ReactiveAdapterRegistryTests { public void reactivexFlowableToPublisher() throws Exception { List sequence = Arrays.asList(1, 2, 3); Object source = io.reactivex.Flowable.fromIterable(sequence); - Object target = getAdapterFrom(io.reactivex.Flowable.class).toPublisher(source); + Object target = getAdapter(io.reactivex.Flowable.class).toPublisher(source); assertTrue("Expected Flux Publisher: " + target.getClass().getName(), target instanceof Flux); assertEquals(sequence, ((Flux) target).collectList().blockMillis(1000)); } @@ -201,7 +227,7 @@ public class ReactiveAdapterRegistryTests { public void reactivexObservableToPublisher() throws Exception { List sequence = Arrays.asList(1, 2, 3); Object source = io.reactivex.Observable.fromIterable(sequence); - Object target = getAdapterFrom(io.reactivex.Observable.class).toPublisher(source); + Object target = getAdapter(io.reactivex.Observable.class).toPublisher(source); assertTrue("Expected Flux Publisher: " + target.getClass().getName(), target instanceof Flux); assertEquals(sequence, ((Flux) target).collectList().blockMillis(1000)); } @@ -209,7 +235,7 @@ public class ReactiveAdapterRegistryTests { @Test public void reactivexSingleToPublisher() throws Exception { Object source = io.reactivex.Single.just(1); - Object target = getAdapterFrom(io.reactivex.Single.class).toPublisher(source); + Object target = getAdapter(io.reactivex.Single.class).toPublisher(source); assertTrue("Expected Mono Publisher: " + target.getClass().getName(), target instanceof Mono); assertEquals(new Integer(1), ((Mono) target).blockMillis(1000)); } @@ -217,7 +243,7 @@ public class ReactiveAdapterRegistryTests { @Test public void reactivexCompletableToPublisher() throws Exception { Object source = io.reactivex.Completable.complete(); - Object target = getAdapterFrom(io.reactivex.Completable.class).toPublisher(source); + Object target = getAdapter(io.reactivex.Completable.class).toPublisher(source); assertTrue("Expected Mono Publisher: " + target.getClass().getName(), target instanceof Mono); ((Mono) target).blockMillis(1000); } @@ -226,18 +252,14 @@ public class ReactiveAdapterRegistryTests { public void CompletableFutureToPublisher() throws Exception { CompletableFuture future = new CompletableFuture(); future.complete(1); - Object target = getAdapterFrom(CompletableFuture.class).toPublisher(future); + Object target = getAdapter(CompletableFuture.class).toPublisher(future); assertTrue("Expected Mono Publisher: " + target.getClass().getName(), target instanceof Mono); assertEquals(new Integer(1), ((Mono) target).blockMillis(1000)); } - private ReactiveAdapter getAdapterTo(Class reactiveType) { - return this.registry.getAdapterTo(reactiveType); - } - - private ReactiveAdapter getAdapterFrom(Class reactiveType) { - return this.registry.getAdapterFrom(reactiveType); + private ReactiveAdapter getAdapter(Class reactiveType) { + return this.registry.getAdapter(reactiveType); } } diff --git a/spring-web-reactive/src/main/java/org/springframework/web/reactive/result/method/annotation/AbstractMessageReaderArgumentResolver.java b/spring-web-reactive/src/main/java/org/springframework/web/reactive/result/method/annotation/AbstractMessageReaderArgumentResolver.java index c5c11b3b77..8f82dd27de 100644 --- a/spring-web-reactive/src/main/java/org/springframework/web/reactive/result/method/annotation/AbstractMessageReaderArgumentResolver.java +++ b/spring-web-reactive/src/main/java/org/springframework/web/reactive/result/method/annotation/AbstractMessageReaderArgumentResolver.java @@ -112,7 +112,7 @@ public abstract class AbstractMessageReaderArgumentResolver { BindingContext bindingContext, ServerWebExchange exchange) { ResolvableType bodyType = ResolvableType.forMethodParameter(bodyParameter); - ReactiveAdapter adapter = getAdapterRegistry().getAdapterTo(bodyType.resolve()); + ReactiveAdapter adapter = getAdapterRegistry().getAdapter(bodyType.resolve()); ResolvableType elementType = ResolvableType.forMethodParameter(bodyParameter); if (adapter != null) { @@ -130,7 +130,7 @@ public abstract class AbstractMessageReaderArgumentResolver { if (reader.canRead(elementType, mediaType)) { Map readHints = Collections.emptyMap(); - if (adapter != null && adapter.getDescriptor().isMultiValue()) { + if (adapter != null && adapter.isMultiValue()) { Flux flux; if (reader instanceof ServerHttpMessageReader) { ServerHttpMessageReader serverReader = ((ServerHttpMessageReader) reader); @@ -186,7 +186,7 @@ public abstract class AbstractMessageReaderArgumentResolver { } protected boolean checkRequired(ReactiveAdapter adapter, boolean isBodyRequired) { - return adapter != null && !adapter.getDescriptor().supportsEmpty() || isBodyRequired; + return adapter != null && !adapter.supportsEmpty() || isBodyRequired; } protected ServerWebInputException getRequiredBodyError(MethodParameter parameter) { diff --git a/spring-web-reactive/src/main/java/org/springframework/web/reactive/result/method/annotation/AbstractMessageWriterResultHandler.java b/spring-web-reactive/src/main/java/org/springframework/web/reactive/result/method/annotation/AbstractMessageWriterResultHandler.java index 1ffcf87d39..5aaa381a07 100644 --- a/spring-web-reactive/src/main/java/org/springframework/web/reactive/result/method/annotation/AbstractMessageWriterResultHandler.java +++ b/spring-web-reactive/src/main/java/org/springframework/web/reactive/result/method/annotation/AbstractMessageWriterResultHandler.java @@ -95,19 +95,19 @@ public abstract class AbstractMessageWriterResultHandler extends AbstractHandler ResolvableType valueType = ResolvableType.forMethodParameter(bodyParameter); Class valueClass = valueType.resolve(); - ReactiveAdapter adapter = getAdapterRegistry().getAdapterFrom(valueClass, body); + ReactiveAdapter adapter = getAdapterRegistry().getAdapter(valueClass, body); Publisher publisher; ResolvableType elementType; if (adapter != null) { publisher = adapter.toPublisher(body); - elementType = adapter.getDescriptor().isNoValue() ? - ResolvableType.forClass(Void.class) : - valueType.getGeneric(0); + elementType = adapter.isNoValue() ? + ResolvableType.forClass(Void.class) : valueType.getGeneric(0); } else { publisher = Mono.justOrEmpty(body); - elementType = (valueClass == null && body != null ? ResolvableType.forInstance(body) : valueType); + elementType = (valueClass == null && body != null ? + ResolvableType.forInstance(body) : valueType); } if (void.class == elementType.getRawClass() || Void.class == elementType.getRawClass()) { diff --git a/spring-web-reactive/src/main/java/org/springframework/web/reactive/result/method/annotation/BindingContextFactory.java b/spring-web-reactive/src/main/java/org/springframework/web/reactive/result/method/annotation/BindingContextFactory.java index 93609de351..4e6f677fe0 100644 --- a/spring-web-reactive/src/main/java/org/springframework/web/reactive/result/method/annotation/BindingContextFactory.java +++ b/spring-web-reactive/src/main/java/org/springframework/web/reactive/result/method/annotation/BindingContextFactory.java @@ -145,7 +145,7 @@ class BindingContextFactory { } ResolvableType type = result.getReturnType(); - ReactiveAdapter adapter = getAdapterRegistry().getAdapterFrom(type.getRawClass(), value); + ReactiveAdapter adapter = getAdapterRegistry().getAdapter(type.getRawClass(), value); Class valueType = (adapter != null ? type.resolveGeneric(0) : type.resolve()); if (Void.class.equals(valueType) || void.class.equals(valueType)) { diff --git a/spring-web-reactive/src/main/java/org/springframework/web/reactive/result/method/annotation/ErrorsMethodArgumentResolver.java b/spring-web-reactive/src/main/java/org/springframework/web/reactive/result/method/annotation/ErrorsMethodArgumentResolver.java index 06bd277e35..6318cb3b54 100644 --- a/spring-web-reactive/src/main/java/org/springframework/web/reactive/result/method/annotation/ErrorsMethodArgumentResolver.java +++ b/spring-web-reactive/src/main/java/org/springframework/web/reactive/result/method/annotation/ErrorsMethodArgumentResolver.java @@ -102,9 +102,9 @@ public class ErrorsMethodArgumentResolver implements HandlerMethodArgumentResolv Class attributeType = attributeParam.getParameterType(); ResolvableType type = ResolvableType.forMethodParameter(attributeParam); - ReactiveAdapter adapterTo = getAdapterRegistry().getAdapterTo(type.resolve()); + ReactiveAdapter adapter = getAdapterRegistry().getAdapter(type.resolve()); - Assert.isNull(adapterTo, "Errors/BindingResult cannot be used with an async model attribute. " + + Assert.isNull(adapter, "Errors/BindingResult cannot be used with an async model attribute. " + "Either declare the model attribute without the async wrapper type " + "or handle WebExchangeBindException through the async type."); diff --git a/spring-web-reactive/src/main/java/org/springframework/web/reactive/result/method/annotation/ModelAttributeMethodArgumentResolver.java b/spring-web-reactive/src/main/java/org/springframework/web/reactive/result/method/annotation/ModelAttributeMethodArgumentResolver.java index ddd3229bcc..6ac46ad8b7 100644 --- a/spring-web-reactive/src/main/java/org/springframework/web/reactive/result/method/annotation/ModelAttributeMethodArgumentResolver.java +++ b/spring-web-reactive/src/main/java/org/springframework/web/reactive/result/method/annotation/ModelAttributeMethodArgumentResolver.java @@ -105,10 +105,9 @@ public class ModelAttributeMethodArgumentResolver implements HandlerMethodArgume } if (this.useDefaultResolution) { Class clazz = parameter.getParameterType(); - ReactiveAdapter adapter = getAdapterRegistry().getAdapterFrom(clazz); + ReactiveAdapter adapter = getAdapterRegistry().getAdapter(clazz); if (adapter != null) { - ReactiveTypeDescriptor descriptor = adapter.getDescriptor(); - if (descriptor.isNoValue() || descriptor.isMultiValue()) { + if (adapter.isNoValue() || adapter.isMultiValue()) { return false; } clazz = ResolvableType.forMethodParameter(parameter).getGeneric(0).getRawClass(); @@ -123,8 +122,8 @@ public class ModelAttributeMethodArgumentResolver implements HandlerMethodArgume ServerWebExchange exchange) { ResolvableType type = ResolvableType.forMethodParameter(parameter); - ReactiveAdapter adapterTo = getAdapterRegistry().getAdapterTo(type.resolve()); - Class valueType = (adapterTo != null ? type.resolveGeneric(0) : parameter.getParameterType()); + ReactiveAdapter adapter = getAdapterRegistry().getAdapter(type.resolve()); + Class valueType = (adapter != null ? type.resolveGeneric(0) : parameter.getParameterType()); String name = getAttributeName(valueType, parameter); Mono valueMono = getAttributeMono(name, valueType, parameter, context, exchange); @@ -145,8 +144,8 @@ public class ModelAttributeMethodArgumentResolver implements HandlerMethodArgume }) .then(Mono.fromCallable(() -> { BindingResult errors = binder.getBindingResult(); - if (adapterTo != null) { - return adapterTo.fromPublisher(errors.hasErrors() ? + if (adapter != null) { + return adapter.fromPublisher(errors.hasErrors() ? Mono.error(new WebExchangeBindException(parameter, errors)) : Mono.just(value)); } @@ -177,10 +176,9 @@ public class ModelAttributeMethodArgumentResolver implements HandlerMethodArgume attribute = createAttribute(attributeName, attributeType, param, context, exchange); } if (attribute != null) { - ReactiveAdapter adapterFrom = getAdapterRegistry().getAdapterFrom(null, attribute); + ReactiveAdapter adapterFrom = getAdapterRegistry().getAdapter(null, attribute); if (adapterFrom != null) { - ReactiveTypeDescriptor descriptor = adapterFrom.getDescriptor(); - Assert.isTrue(!descriptor.isMultiValue(), "Data binding supports single-value async types."); + Assert.isTrue(!adapterFrom.isMultiValue(), "Data binding supports single-value async types."); return Mono.from(adapterFrom.toPublisher(attribute)); } } diff --git a/spring-web-reactive/src/main/java/org/springframework/web/reactive/result/method/annotation/ResponseBodyResultHandler.java b/spring-web-reactive/src/main/java/org/springframework/web/reactive/result/method/annotation/ResponseBodyResultHandler.java index ad635480a0..7d0a403882 100644 --- a/spring-web-reactive/src/main/java/org/springframework/web/reactive/result/method/annotation/ResponseBodyResultHandler.java +++ b/spring-web-reactive/src/main/java/org/springframework/web/reactive/result/method/annotation/ResponseBodyResultHandler.java @@ -17,7 +17,6 @@ package org.springframework.web.reactive.result.method.annotation; import java.util.List; -import java.util.Optional; import reactor.core.publisher.Mono; @@ -103,8 +102,8 @@ public class ResponseBodyResultHandler extends AbstractMessageWriterResultHandle return true; } else { - ReactiveAdapter adapter = getAdapterRegistry().getAdapterFrom(rawClass, result.getReturnValue()); - if (adapter != null && !adapter.getDescriptor().isNoValue()) { + ReactiveAdapter adapter = getAdapterRegistry().getAdapter(rawClass, result.getReturnValue()); + if (adapter != null && !adapter.isNoValue()) { ResolvableType genericType = result.getReturnType().getGeneric(0); if (HttpEntity.class.isAssignableFrom(genericType.getRawClass())) { return true; diff --git a/spring-web-reactive/src/main/java/org/springframework/web/reactive/result/method/annotation/ResponseEntityResultHandler.java b/spring-web-reactive/src/main/java/org/springframework/web/reactive/result/method/annotation/ResponseEntityResultHandler.java index b62ffea09e..64d97e9581 100644 --- a/spring-web-reactive/src/main/java/org/springframework/web/reactive/result/method/annotation/ResponseEntityResultHandler.java +++ b/spring-web-reactive/src/main/java/org/springframework/web/reactive/result/method/annotation/ResponseEntityResultHandler.java @@ -25,7 +25,6 @@ import reactor.core.publisher.Mono; import org.springframework.core.MethodParameter; import org.springframework.core.ReactiveAdapter; import org.springframework.core.ReactiveAdapterRegistry; -import org.springframework.core.ReactiveTypeDescriptor; import org.springframework.core.ResolvableType; import org.springframework.http.HttpEntity; import org.springframework.http.HttpHeaders; @@ -91,11 +90,8 @@ public class ResponseEntityResultHandler extends AbstractMessageWriterResultHand return true; } else { - ReactiveAdapter adapter = getAdapterRegistry().getAdapterFrom(returnType, result.getReturnValue()); - if (adapter != null && - !adapter.getDescriptor().isMultiValue() && - !adapter.getDescriptor().isNoValue()) { - + ReactiveAdapter adapter = getAdapterRegistry().getAdapter(returnType, result.getReturnValue()); + if (adapter != null && !adapter.isMultiValue() && !adapter.isNoValue()) { ResolvableType genericType = result.getReturnType().getGeneric(0); return isSupportedType(genericType.getRawClass()); } @@ -118,11 +114,10 @@ public class ResponseEntityResultHandler extends AbstractMessageWriterResultHand Optional optionalValue = result.getReturnValue(); Class rawClass = returnType.getRawClass(); - ReactiveAdapter adapter = getAdapterRegistry().getAdapterFrom(rawClass, optionalValue); + ReactiveAdapter adapter = getAdapterRegistry().getAdapter(rawClass, optionalValue); if (adapter != null) { - ReactiveTypeDescriptor descriptor = adapter.getDescriptor(); - Assert.isTrue(!descriptor.isMultiValue(), "Only a single ResponseEntity supported."); + Assert.isTrue(!adapter.isMultiValue(), "Only a single ResponseEntity supported."); returnValueMono = Mono.from(adapter.toPublisher(optionalValue)); bodyType = new MethodParameter(result.getReturnTypeSource()); bodyType.increaseNestingLevel(); diff --git a/spring-web-reactive/src/main/java/org/springframework/web/reactive/result/view/ViewResolutionResultHandler.java b/spring-web-reactive/src/main/java/org/springframework/web/reactive/result/view/ViewResolutionResultHandler.java index b0b53a355f..184d4c81de 100644 --- a/spring-web-reactive/src/main/java/org/springframework/web/reactive/result/view/ViewResolutionResultHandler.java +++ b/spring-web-reactive/src/main/java/org/springframework/web/reactive/result/view/ViewResolutionResultHandler.java @@ -33,7 +33,6 @@ import org.springframework.core.MethodParameter; import org.springframework.core.Ordered; import org.springframework.core.ReactiveAdapter; import org.springframework.core.ReactiveAdapterRegistry; -import org.springframework.core.ReactiveTypeDescriptor; import org.springframework.core.ResolvableType; import org.springframework.core.annotation.AnnotationAwareOrderComparator; import org.springframework.http.MediaType; @@ -154,9 +153,9 @@ public class ViewResolutionResultHandler extends AbstractHandlerResultHandler return true; } Optional optional = result.getReturnValue(); - ReactiveAdapter adapter = getAdapterRegistry().getAdapterFrom(clazz, optional); + ReactiveAdapter adapter = getAdapterRegistry().getAdapter(clazz, optional); if (adapter != null) { - if (adapter.getDescriptor().isNoValue()) { + if (adapter.isNoValue()) { return true; } else { @@ -190,15 +189,14 @@ public class ViewResolutionResultHandler extends AbstractHandlerResultHandler ResolvableType parameterType = result.getReturnType(); Optional optional = result.getReturnValue(); - ReactiveAdapter adapter = getAdapterRegistry().getAdapterFrom(parameterType.getRawClass(), optional); + ReactiveAdapter adapter = getAdapterRegistry().getAdapter(parameterType.getRawClass(), optional); if (adapter != null) { - ReactiveTypeDescriptor descriptor = adapter.getDescriptor(); - Assert.isTrue(!descriptor.isMultiValue(), "Only single-value async return type supported."); + Assert.isTrue(!adapter.isMultiValue(), "Only single-value async return type supported."); returnValueMono = optional .map(value -> Mono.from(adapter.toPublisher(value))) .orElse(Mono.empty()); - elementType = !adapter.getDescriptor().isNoValue() ? + elementType = !adapter.isNoValue() ? parameterType.getGeneric(0) : ResolvableType.forClass(Void.class); } else { @@ -301,10 +299,10 @@ public class ViewResolutionResultHandler extends AbstractHandlerResultHandler List> valueMonos = new ArrayList<>(); for (Map.Entry entry : model.entrySet()) { - ReactiveAdapter adapter = getAdapterRegistry().getAdapterFrom(null, entry.getValue()); + ReactiveAdapter adapter = getAdapterRegistry().getAdapter(null, entry.getValue()); if (adapter != null) { names.add(entry.getKey()); - if (adapter.getDescriptor().isMultiValue()) { + if (adapter.isMultiValue()) { Flux value = Flux.from(adapter.toPublisher(entry.getValue())); valueMonos.add(value.collectList().defaultIfEmpty(Collections.emptyList())); } -- GitLab