Polish
This commit is contained in:
parent
fee63fdfb8
commit
0db216daab
|
|
@ -20,21 +20,25 @@ import org.springframework.core.MethodParameter;
|
|||
import org.springframework.messaging.Message;
|
||||
|
||||
/**
|
||||
* Abstract base class for {@link AsyncHandlerMethodReturnValueHandler} implementations
|
||||
* only intended for asynchronous return value handling.
|
||||
* Convenient base class for {@link AsyncHandlerMethodReturnValueHandler}
|
||||
* implementations that support only asynchronous (Future-like) return values a
|
||||
* and merely serve as adapters of such types to Spring's
|
||||
* {@link org.springframework.util.concurrent.ListenableFuture ListenableFuture}.
|
||||
*
|
||||
* @author Sebastien Deleuze
|
||||
* @since 4.2
|
||||
*/
|
||||
public abstract class AbstractAsyncReturnValueHandler implements AsyncHandlerMethodReturnValueHandler {
|
||||
|
||||
@Override
|
||||
public void handleReturnValue(Object returnValue, MethodParameter returnType, Message<?> message) throws Exception {
|
||||
throw new UnsupportedOperationException("Not supported");
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean isAsyncReturnValue(Object returnValue, MethodParameter returnType) {
|
||||
return true;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void handleReturnValue(Object returnValue, MethodParameter returnType, Message<?> message) {
|
||||
// Should never be called since we return "true" from isAsyncReturnValue
|
||||
throw new IllegalStateException("Unexpected invocation.");
|
||||
}
|
||||
|
||||
}
|
||||
|
|
|
|||
|
|
@ -467,7 +467,7 @@ public abstract class AbstractMethodMessageHandler<T>
|
|||
if (this.returnValueHandlers.isAsyncReturnValue(returnValue, returnType)) {
|
||||
ListenableFuture<?> future = this.returnValueHandlers.toListenableFuture(returnValue, returnType);
|
||||
if (future != null) {
|
||||
future.addCallback(new ReturnValueListenableFutureCallback(returnType, invocable, message));
|
||||
future.addCallback(new ReturnValueListenableFutureCallback(invocable, message));
|
||||
}
|
||||
}
|
||||
else {
|
||||
|
|
@ -596,17 +596,12 @@ public abstract class AbstractMethodMessageHandler<T>
|
|||
|
||||
private class ReturnValueListenableFutureCallback implements ListenableFutureCallback<Object> {
|
||||
|
||||
private final MethodParameter returnType;
|
||||
|
||||
private final InvocableHandlerMethod handlerMethod;
|
||||
|
||||
private final Message<?> message;
|
||||
|
||||
|
||||
public ReturnValueListenableFutureCallback(MethodParameter returnType,
|
||||
InvocableHandlerMethod handlerMethod, Message<?> message) {
|
||||
|
||||
this.returnType = returnType;
|
||||
public ReturnValueListenableFutureCallback(InvocableHandlerMethod handlerMethod, Message<?> message) {
|
||||
this.handlerMethod = handlerMethod;
|
||||
this.message = message;
|
||||
}
|
||||
|
|
@ -614,7 +609,8 @@ public abstract class AbstractMethodMessageHandler<T>
|
|||
@Override
|
||||
public void onSuccess(Object result) {
|
||||
try {
|
||||
returnValueHandlers.handleReturnValue(result, handlerMethod.getAsyncReturnValueType(result), this.message);
|
||||
MethodParameter returnType = this.handlerMethod.getAsyncReturnValueType(result);
|
||||
returnValueHandlers.handleReturnValue(result, returnType, this.message);
|
||||
}
|
||||
catch (Throwable ex) {
|
||||
handleFailure(ex);
|
||||
|
|
|
|||
|
|
@ -16,14 +16,16 @@
|
|||
package org.springframework.messaging.handler.invocation;
|
||||
|
||||
import org.springframework.core.MethodParameter;
|
||||
import org.springframework.messaging.Message;
|
||||
import org.springframework.util.concurrent.ListenableFuture;
|
||||
|
||||
/**
|
||||
* An extension of {@link HandlerMethodReturnValueHandler} for handling async
|
||||
* return value types.
|
||||
* An extension of {@link HandlerMethodReturnValueHandler} for handling async,
|
||||
* Future-like return value types that support success and error callbacks.
|
||||
* Essentially anything that can be adapted to a {@link ListenableFuture}.
|
||||
*
|
||||
* <p>Implementations only intended for asynchronous return value handling can extend
|
||||
* {@link AbstractAsyncReturnValueHandler}.</p>
|
||||
* <p>Implementations should consider extending the convenient base class
|
||||
* {@link AbstractAsyncReturnValueHandler}.
|
||||
*
|
||||
* @author Rossen Stoyanchev
|
||||
* @since 4.2
|
||||
|
|
@ -32,30 +34,36 @@ import org.springframework.util.concurrent.ListenableFuture;
|
|||
public interface AsyncHandlerMethodReturnValueHandler extends HandlerMethodReturnValueHandler {
|
||||
|
||||
/**
|
||||
* Whether the return value type represents a value that will be produced
|
||||
* asynchronously. If this method returns {@code true}, the
|
||||
* {@link #toListenableFuture(Object, MethodParameter)} will be invoked next.
|
||||
* @param returnValue the value returned from the handler method
|
||||
* @param returnType the type of the return value. This type must have
|
||||
* previously been passed to
|
||||
* Whether the return value represents an asynchronous, Future-like type
|
||||
* with success and error callbacks. If this method returns {@code true},
|
||||
* then {@link #toListenableFuture} is invoked next. If it returns
|
||||
* {@code false}, then {@link #handleReturnValue} is called.
|
||||
*
|
||||
* <p><strong>Note:</strong> this method will only be invoked after
|
||||
* {@link #supportsReturnType(org.springframework.core.MethodParameter)}
|
||||
* and it must have returned {@code true}
|
||||
* is called and it returns {@code true}.
|
||||
*
|
||||
* @param returnValue the value returned from the handler method
|
||||
* @param returnType the type of the return value.
|
||||
* @return true if the return value type represents an async value.
|
||||
*/
|
||||
boolean isAsyncReturnValue(Object returnValue, MethodParameter returnType);
|
||||
|
||||
/**
|
||||
* Adapt the given asynchronous return value to a ListenableFuture.
|
||||
* Implementations can return an instance of
|
||||
* {@link org.springframework.util.concurrent.SettableListenableFuture} and
|
||||
* then set it to an Object (success) or a Throwable (failure) to complete
|
||||
* handling.
|
||||
* @param returnValue the value returned from the handler method
|
||||
* @param returnType the type of the return value. This type must have
|
||||
* previously been passed to
|
||||
* Adapt the asynchronous return value to a {@link ListenableFuture}.
|
||||
* Implementations should consider returning an instance of
|
||||
* {@link org.springframework.util.concurrent.SettableListenableFuture
|
||||
* SettableListenableFuture}. Return value handling will then continue when
|
||||
* the ListenableFuture is completed with either success or error.
|
||||
*
|
||||
* <p><strong>Note:</strong> this method will only be invoked after
|
||||
* {@link #supportsReturnType(org.springframework.core.MethodParameter)}
|
||||
* and it must have returned {@code true}
|
||||
* @return a ListenableFuture
|
||||
* is called and it returns {@code true}.
|
||||
*
|
||||
* @param returnValue the value returned from the handler method
|
||||
* @param returnType the type of the return value.
|
||||
* @return the resulting ListenableFuture or {@code null} in which case no
|
||||
* further handling will be performed.
|
||||
*/
|
||||
ListenableFuture<?> toListenableFuture(Object returnValue, MethodParameter returnType);
|
||||
|
||||
|
|
|
|||
|
|
@ -24,7 +24,7 @@ import org.springframework.util.concurrent.CompletableToListenableFutureAdapter;
|
|||
import org.springframework.util.concurrent.ListenableFuture;
|
||||
|
||||
/**
|
||||
* An {@link AsyncHandlerMethodReturnValueHandler} for {@link CompletableFuture} return type handling.
|
||||
* Support for {@link CompletableFuture} as a return value type.
|
||||
*
|
||||
* @author Sebastien Deleuze
|
||||
* @since 4.2
|
||||
|
|
@ -40,7 +40,7 @@ public class CompletableFutureReturnValueHandler extends AbstractAsyncReturnValu
|
|||
@Override
|
||||
@SuppressWarnings("unchecked")
|
||||
public ListenableFuture<?> toListenableFuture(Object returnValue, MethodParameter returnType) {
|
||||
return new CompletableToListenableFutureAdapter<Object>((CompletableFuture<Object>)returnValue);
|
||||
return new CompletableToListenableFutureAdapter<Object>((CompletableFuture<Object>) returnValue);
|
||||
}
|
||||
|
||||
}
|
||||
|
|
@ -104,12 +104,8 @@ public class HandlerMethodReturnValueHandlerComposite implements AsyncHandlerMet
|
|||
@Override
|
||||
public boolean isAsyncReturnValue(Object returnValue, MethodParameter returnType) {
|
||||
HandlerMethodReturnValueHandler handler = getReturnValueHandler(returnType);
|
||||
if (handler != null && handler instanceof AsyncHandlerMethodReturnValueHandler) {
|
||||
if (((AsyncHandlerMethodReturnValueHandler) handler).isAsyncReturnValue(returnValue, returnType)) {
|
||||
return true;
|
||||
}
|
||||
}
|
||||
return false;
|
||||
return (handler != null && handler instanceof AsyncHandlerMethodReturnValueHandler &&
|
||||
((AsyncHandlerMethodReturnValueHandler) handler).isAsyncReturnValue(returnValue, returnType));
|
||||
}
|
||||
|
||||
@Override
|
||||
|
|
|
|||
|
|
@ -28,7 +28,6 @@ import org.springframework.core.ParameterNameDiscoverer;
|
|||
import org.springframework.core.ResolvableType;
|
||||
import org.springframework.messaging.Message;
|
||||
import org.springframework.messaging.handler.HandlerMethod;
|
||||
import org.springframework.util.Assert;
|
||||
import org.springframework.util.ReflectionUtils;
|
||||
|
||||
/**
|
||||
|
|
@ -152,15 +151,15 @@ public class InvocableHandlerMethod extends HandlerMethod {
|
|||
}
|
||||
|
||||
/**
|
||||
* Adds HandlerMethod details such as the controller type and method signature to the given error message.
|
||||
* Adds HandlerMethod details such as the controller type and method
|
||||
* signature to the given error message.
|
||||
* @param message error message to append the HandlerMethod details to
|
||||
*/
|
||||
protected String getDetailedErrorMessage(String message) {
|
||||
StringBuilder sb = new StringBuilder(message).append("\n");
|
||||
sb.append("HandlerMethod details: \n");
|
||||
sb.append("Controller [").append(getBeanType().getName()).append("]\n");
|
||||
sb.append("Method [").append(getBridgedMethod().toGenericString()).append("]\n");
|
||||
return sb.toString();
|
||||
return message + "\n" +
|
||||
"HandlerMethod details: \n" +
|
||||
"Controller [" + getBeanType().getName() + "]\n" +
|
||||
"Method [" + getBridgedMethod().toGenericString() + "]\n";
|
||||
}
|
||||
|
||||
/**
|
||||
|
|
@ -249,6 +248,7 @@ public class InvocableHandlerMethod extends HandlerMethod {
|
|||
return new AsyncResultMethodParameter(returnValue);
|
||||
}
|
||||
|
||||
|
||||
private class AsyncResultMethodParameter extends HandlerMethodParameter {
|
||||
|
||||
private final Object returnValue;
|
||||
|
|
@ -266,7 +266,9 @@ public class InvocableHandlerMethod extends HandlerMethod {
|
|||
if (this.returnValue != null) {
|
||||
return this.returnValue.getClass();
|
||||
}
|
||||
Assert.isTrue(!ResolvableType.NONE.equals(this.returnType), "Expected Future-like type with generic parameter");
|
||||
if (ResolvableType.NONE.equals(this.returnType)) {
|
||||
throw new IllegalArgumentException("Expected Future-like type with generic parameter");
|
||||
}
|
||||
return this.returnType.getRawClass();
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -20,7 +20,7 @@ import org.springframework.core.MethodParameter;
|
|||
import org.springframework.util.concurrent.ListenableFuture;
|
||||
|
||||
/**
|
||||
* An {@link AsyncHandlerMethodReturnValueHandler} for {@link ListenableFuture} return type handling.
|
||||
* Support for {@link ListenableFuture} as a return value type.
|
||||
*
|
||||
* @author Sebastien Deleuze
|
||||
* @since 4.2
|
||||
|
|
@ -35,7 +35,7 @@ public class ListenableFutureReturnValueHandler extends AbstractAsyncReturnValue
|
|||
@Override
|
||||
@SuppressWarnings("unchecked")
|
||||
public ListenableFuture<?> toListenableFuture(Object returnValue, MethodParameter returnType) {
|
||||
return (ListenableFuture<?>)returnValue;
|
||||
return (ListenableFuture<?>) returnValue;
|
||||
}
|
||||
|
||||
}
|
||||
|
|
|
|||
|
|
@ -318,14 +318,13 @@ public class SimpAnnotationMethodMessageHandler extends AbstractMethodMessageHan
|
|||
|
||||
@Override
|
||||
protected List<? extends HandlerMethodReturnValueHandler> initReturnValueHandlers() {
|
||||
|
||||
List<HandlerMethodReturnValueHandler> handlers = new ArrayList<HandlerMethodReturnValueHandler>();
|
||||
|
||||
// Single-purpose return value types
|
||||
ListenableFutureReturnValueHandler lfh = new ListenableFutureReturnValueHandler();
|
||||
handlers.add(lfh);
|
||||
handlers.add(new ListenableFutureReturnValueHandler());
|
||||
if (completableFuturePresent) {
|
||||
CompletableFutureReturnValueHandler cfh = new CompletableFutureReturnValueHandler();
|
||||
handlers.add(cfh);
|
||||
handlers.add(new CompletableFutureReturnValueHandler());
|
||||
}
|
||||
|
||||
// Annotation-based return value types
|
||||
|
|
|
|||
Loading…
Reference in New Issue