Support CompletableFuture in @MessageMapping handler methods

Issue: SPR-12207
This commit is contained in:
Sebastien Deleuze
2015-05-22 11:24:54 +02:00
parent d3db99c201
commit 5255e7ae21
4 changed files with 212 additions and 0 deletions

View File

@@ -0,0 +1,46 @@
/*
* Copyright 2002-2015 the original author or authors.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package org.springframework.messaging.handler.invocation;
import java.util.concurrent.CompletableFuture;
import org.springframework.core.MethodParameter;
import org.springframework.lang.UsesJava8;
import org.springframework.util.concurrent.CompletableToListenableFutureAdapter;
import org.springframework.util.concurrent.ListenableFuture;
/**
* An {@link AsyncHandlerMethodReturnValueHandler} for {@link CompletableFuture} return type handling.
*
* @author Sebastien Deleuze
* @since 4.2
*/
@UsesJava8
public class CompletableFutureReturnValueHandler extends AbstractAsyncReturnValueHandler {
@Override
public boolean supportsReturnType(MethodParameter returnType) {
return CompletableFuture.class.isAssignableFrom(returnType.getParameterType());
}
@Override
@SuppressWarnings("unchecked")
public ListenableFuture<?> toListenableFuture(Object returnValue, MethodParameter returnType) {
return new CompletableToListenableFutureAdapter<Object>((CompletableFuture<Object>)returnValue);
}
}

View File

@@ -50,6 +50,7 @@ import org.springframework.messaging.handler.annotation.support.MessageMethodArg
import org.springframework.messaging.handler.annotation.support.PayloadArgumentResolver;
import org.springframework.messaging.handler.invocation.AbstractExceptionHandlerMethodResolver;
import org.springframework.messaging.handler.invocation.AbstractMethodMessageHandler;
import org.springframework.messaging.handler.invocation.CompletableFutureReturnValueHandler;
import org.springframework.messaging.handler.invocation.HandlerMethodArgumentResolver;
import org.springframework.messaging.handler.invocation.HandlerMethodReturnValueHandler;
import org.springframework.messaging.handler.invocation.ListenableFutureReturnValueHandler;
@@ -83,6 +84,10 @@ import org.springframework.validation.Validator;
public class SimpAnnotationMethodMessageHandler extends AbstractMethodMessageHandler<SimpMessageMappingInfo>
implements SmartLifecycle {
private static final boolean completableFuturePresent = ClassUtils.isPresent("java.util.concurrent.CompletableFuture",
SimpAnnotationMethodMessageHandler.class.getClassLoader());
private final SubscribableChannel clientInboundChannel;
private final SimpMessageSendingOperations clientMessagingTemplate;
@@ -318,6 +323,10 @@ public class SimpAnnotationMethodMessageHandler extends AbstractMethodMessageHan
// Single-purpose return value types
ListenableFutureReturnValueHandler lfh = new ListenableFutureReturnValueHandler();
handlers.add(lfh);
if (completableFuturePresent) {
CompletableFutureReturnValueHandler cfh = new CompletableFutureReturnValueHandler();
handlers.add(cfh);
}
// Annotation-based return value types
SendToMethodReturnValueHandler sth = new SendToMethodReturnValueHandler(this.brokerTemplate, true);