diff --git a/spring-webflux/src/main/java/org/springframework/web/reactive/result/method/InvocableHandlerMethod.java b/spring-webflux/src/main/java/org/springframework/web/reactive/result/method/InvocableHandlerMethod.java index 3052c5160c8..b7a6811f9d0 100644 --- a/spring-webflux/src/main/java/org/springframework/web/reactive/result/method/InvocableHandlerMethod.java +++ b/spring-webflux/src/main/java/org/springframework/web/reactive/result/method/InvocableHandlerMethod.java @@ -43,8 +43,9 @@ import org.springframework.web.reactive.HandlerResult; import org.springframework.web.server.ServerWebExchange; /** - * A subclass of {@link HandlerMethod} that can resolve method arguments from - * a {@link ServerWebExchange} and use that to invoke the underlying method. + * Extension of {@link HandlerMethod} that invokes the underlying method with + * argument values resolved from the current HTTP request through a list of + * {@link HandlerMethodArgumentResolver}. * * @author Rossen Stoyanchev * @author Juergen Hoeller @@ -94,7 +95,7 @@ public class InvocableHandlerMethod extends HandlerMethod { } /** - * Return the conifgured argument resolvers. + * Return the configured argument resolvers. */ public List getResolvers() { return this.resolvers; diff --git a/spring-webflux/src/main/java/org/springframework/web/reactive/result/method/SyncInvocableHandlerMethod.java b/spring-webflux/src/main/java/org/springframework/web/reactive/result/method/SyncInvocableHandlerMethod.java index c776cbe85ca..f7365d363f5 100644 --- a/spring-webflux/src/main/java/org/springframework/web/reactive/result/method/SyncInvocableHandlerMethod.java +++ b/spring-webflux/src/main/java/org/springframework/web/reactive/result/method/SyncInvocableHandlerMethod.java @@ -19,69 +19,85 @@ package org.springframework.web.reactive.result.method; import java.lang.reflect.Method; import java.util.ArrayList; import java.util.List; +import java.util.stream.Collectors; -import org.springframework.util.Assert; +import org.springframework.core.DefaultParameterNameDiscoverer; +import org.springframework.core.ParameterNameDiscoverer; import org.springframework.web.method.HandlerMethod; import org.springframework.web.reactive.BindingContext; import org.springframework.web.reactive.HandlerResult; import org.springframework.web.server.ServerWebExchange; /** - * Extension of {@code InvocableHandlerMethod} that can only be configured with - * synchronous argument resolvers and thus exposing an additional, synchronous - * {@link #invokeForHandlerResult} returning a {@code HandlerResult} vs - * {@code Mono}. + * Extension of {@link HandlerMethod} that invokes the underlying method via + * {@link InvocableHandlerMethod} but uses sync argument resolvers only and + * thus can return directly a {@link HandlerResult} with no async wrappers. * * @author Rossen Stoyanchev * @since 5.0 */ -public class SyncInvocableHandlerMethod extends InvocableHandlerMethod { +public class SyncInvocableHandlerMethod extends HandlerMethod { + + private final InvocableHandlerMethod delegate; public SyncInvocableHandlerMethod(HandlerMethod handlerMethod) { super(handlerMethod); + this.delegate = new InvocableHandlerMethod(handlerMethod); } public SyncInvocableHandlerMethod(Object bean, Method method) { super(bean, method); + this.delegate = new InvocableHandlerMethod(bean, method); } /** - * {@inheritDoc} - *

Resolvers must be of type {@link SyncHandlerMethodArgumentResolver}. - * @see #setSyncArgumentResolvers(List) + * Configure the argument resolvers to use to use for resolving method + * argument values against a {@code ServerWebExchange}. */ - @Override - public void setArgumentResolvers(List resolvers) { - resolvers.forEach(this::assertSyncResolvers); - super.setArgumentResolvers(resolvers); + public void setArgumentResolvers(List resolvers) { + this.delegate.setArgumentResolvers(new ArrayList<>(resolvers)); } - private void assertSyncResolvers(HandlerMethodArgumentResolver resolver) { - Assert.isInstanceOf(SyncHandlerMethodArgumentResolver.class, resolver, - "SyncInvocableHandlerMethod requires resolvers of type " + - "SyncHandlerMethodArgumentResolver"); + /** + * Return the configured argument resolvers. + */ + public List getResolvers() { + return this.delegate.getResolvers().stream() + .map(resolver -> (SyncHandlerMethodArgumentResolver) resolver) + .collect(Collectors.toList()); + } + + /** + * Set the ParameterNameDiscoverer for resolving parameter names when needed + * (e.g. default request attribute name). + *

Default is a {@link DefaultParameterNameDiscoverer}. + */ + public void setParameterNameDiscoverer(ParameterNameDiscoverer nameDiscoverer) { + this.delegate.setParameterNameDiscoverer(nameDiscoverer); } /** - * Convenient alternative to {@link #setArgumentResolvers(List)} to configure - * synchronous argument resolvers. + * Return the configured parameter name discoverer. */ - public void setSyncArgumentResolvers(List resolvers) { - setArgumentResolvers(new ArrayList<>(resolvers)); + public ParameterNameDiscoverer getParameterNameDiscoverer() { + return this.delegate.getParameterNameDiscoverer(); } /** - * Delegate to the base class {@link #invoke} and also wait for the result. - * Since all argument resolvers are synchronous this won't actually block. + * Invoke the method for the given exchange. + * @param exchange the current exchange + * @param bindingContext the binding context to use + * @param providedArgs optional list of argument values to match by type + * @return Mono with a {@link HandlerResult}. */ public HandlerResult invokeForHandlerResult(ServerWebExchange exchange, BindingContext bindingContext, Object... providedArgs) { // This will not block with only sync resolvers allowed - return super.invoke(exchange, bindingContext, providedArgs).block(); + return this.delegate.invoke(exchange, bindingContext, providedArgs).block(); } } diff --git a/spring-webflux/src/main/java/org/springframework/web/reactive/result/method/annotation/RequestMappingHandlerAdapter.java b/spring-webflux/src/main/java/org/springframework/web/reactive/result/method/annotation/RequestMappingHandlerAdapter.java index 9541f910320..8df4a84c2ee 100644 --- a/spring-webflux/src/main/java/org/springframework/web/reactive/result/method/annotation/RequestMappingHandlerAdapter.java +++ b/spring-webflux/src/main/java/org/springframework/web/reactive/result/method/annotation/RequestMappingHandlerAdapter.java @@ -409,7 +409,7 @@ public class RequestMappingHandlerAdapter implements HandlerAdapter, Application private SyncInvocableHandlerMethod createBinderMethod(Object bean, Method method) { SyncInvocableHandlerMethod invocable = new SyncInvocableHandlerMethod(bean, method); - invocable.setSyncArgumentResolvers(getInitBinderArgumentResolvers()); + invocable.setArgumentResolvers(getInitBinderArgumentResolvers()); return invocable; }