Deprecate ListenableFuture in favor of CompletableFuture
This commit deprecates ListenableFuture in favor of CompletableFuture. ListenableFuture was introduced in Spring Framework 4.0, when CompletableFuture was not yet available. Spring now requires JDK 17, so having our own type no longer seems necessary. Major changes in this commit include: - Deprecation of ListenableFuture and related types (ListenableFutureCallback, SettableListenableFuture, etc.) - Deprecation of AsyncListenableTaskExecutor in favor of default methods in AsyncTaskExecutor (submitCompletable). - AsyncHandlerMethodReturnValueHandler now has toCompletableFuture instead of toListenableFuture. - WebSocketClient now has execute methods, which do the same as doHandshake, but return CompletableFutures (cf. the reactive WebSocketClient). All other changes - add an overloaded method that takes a CompletableFuture parameter instead of ListenableFuture, and/or - add a method with a 'Async' suffix that returns a CompletableFuture instead of a ListenableFuture (connectAsync, sendAsync). Closes gh-27780
This commit is contained in:
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright 2002-2021 the original author or authors.
|
||||
* Copyright 2002-2022 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.
|
||||
@@ -148,7 +148,7 @@ final class DefaultAsyncServerResponse extends ErrorHandlingServerResponse imple
|
||||
else {
|
||||
result = new DeferredResult<>();
|
||||
}
|
||||
this.futureResponse.handle((value, ex) -> {
|
||||
this.futureResponse.whenComplete((value, ex) -> {
|
||||
if (ex != null) {
|
||||
if (ex instanceof CompletionException && ex.getCause() != null) {
|
||||
ex = ex.getCause();
|
||||
@@ -164,7 +164,6 @@ final class DefaultAsyncServerResponse extends ErrorHandlingServerResponse imple
|
||||
else {
|
||||
result.setResult(value);
|
||||
}
|
||||
return null;
|
||||
});
|
||||
return result;
|
||||
}
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright 2002-2021 the original author or authors.
|
||||
* Copyright 2002-2022 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.
|
||||
@@ -366,7 +366,7 @@ final class DefaultEntityResponseBuilder<T> implements EntityResponse.Builder<T>
|
||||
Context context) {
|
||||
|
||||
DeferredResult<ServerResponse> result = new DeferredResult<>();
|
||||
entity().handle((value, ex) -> {
|
||||
entity().whenComplete((value, ex) -> {
|
||||
if (ex != null) {
|
||||
if (ex instanceof CompletionException && ex.getCause() != null) {
|
||||
ex = ex.getCause();
|
||||
@@ -388,7 +388,6 @@ final class DefaultEntityResponseBuilder<T> implements EntityResponse.Builder<T>
|
||||
result.setErrorResult(writeException);
|
||||
}
|
||||
}
|
||||
return null;
|
||||
});
|
||||
return result;
|
||||
}
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright 2002-2019 the original author or authors.
|
||||
* Copyright 2002-2022 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.
|
||||
@@ -18,7 +18,6 @@ package org.springframework.web.servlet.mvc.method.annotation;
|
||||
|
||||
import java.util.concurrent.CompletionException;
|
||||
import java.util.concurrent.CompletionStage;
|
||||
import java.util.function.BiFunction;
|
||||
|
||||
import org.springframework.core.MethodParameter;
|
||||
import org.springframework.lang.Nullable;
|
||||
@@ -39,6 +38,7 @@ import org.springframework.web.method.support.ModelAndViewContainer;
|
||||
*/
|
||||
public class DeferredResultMethodReturnValueHandler implements HandlerMethodReturnValueHandler {
|
||||
|
||||
@SuppressWarnings("deprecation")
|
||||
@Override
|
||||
public boolean supportsReturnType(MethodParameter returnType) {
|
||||
Class<?> type = returnType.getParameterType();
|
||||
@@ -47,6 +47,7 @@ public class DeferredResultMethodReturnValueHandler implements HandlerMethodRetu
|
||||
CompletionStage.class.isAssignableFrom(type));
|
||||
}
|
||||
|
||||
@SuppressWarnings("deprecation")
|
||||
@Override
|
||||
public void handleReturnValue(@Nullable Object returnValue, MethodParameter returnType,
|
||||
ModelAndViewContainer mavContainer, NativeWebRequest webRequest) throws Exception {
|
||||
@@ -75,6 +76,7 @@ public class DeferredResultMethodReturnValueHandler implements HandlerMethodRetu
|
||||
WebAsyncUtils.getAsyncManager(webRequest).startDeferredResultProcessing(result, mavContainer);
|
||||
}
|
||||
|
||||
@SuppressWarnings("deprecation")
|
||||
private DeferredResult<Object> adaptListenableFuture(ListenableFuture<?> future) {
|
||||
DeferredResult<Object> result = new DeferredResult<>();
|
||||
future.addCallback(new ListenableFutureCallback<Object>() {
|
||||
@@ -92,7 +94,7 @@ public class DeferredResultMethodReturnValueHandler implements HandlerMethodRetu
|
||||
|
||||
private DeferredResult<Object> adaptCompletionStage(CompletionStage<?> future) {
|
||||
DeferredResult<Object> result = new DeferredResult<>();
|
||||
future.handle((BiFunction<Object, Throwable, Object>) (value, ex) -> {
|
||||
future.whenComplete((value, ex) -> {
|
||||
if (ex != null) {
|
||||
if (ex instanceof CompletionException && ex.getCause() != null) {
|
||||
ex = ex.getCause();
|
||||
@@ -102,7 +104,6 @@ public class DeferredResultMethodReturnValueHandler implements HandlerMethodRetu
|
||||
else {
|
||||
result.setResult(value);
|
||||
}
|
||||
return null;
|
||||
});
|
||||
return result;
|
||||
}
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright 2002-2019 the original author or authors.
|
||||
* Copyright 2002-2022 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.
|
||||
@@ -89,6 +89,7 @@ public class DeferredResultReturnValueHandlerTests {
|
||||
}
|
||||
|
||||
@Test
|
||||
@SuppressWarnings("deprecation")
|
||||
public void listenableFuture() throws Exception {
|
||||
SettableListenableFuture<String> future = new SettableListenableFuture<>();
|
||||
testHandle(future, ListenableFuture.class, () -> future.set("foo"), "foo");
|
||||
@@ -107,6 +108,7 @@ public class DeferredResultReturnValueHandlerTests {
|
||||
}
|
||||
|
||||
@Test
|
||||
@SuppressWarnings("deprecation")
|
||||
public void listenableFutureWithError() throws Exception {
|
||||
SettableListenableFuture<String> future = new SettableListenableFuture<>();
|
||||
IllegalStateException ex = new IllegalStateException();
|
||||
|
||||
Reference in New Issue
Block a user