1.DeferredResultMethodReturnValueHandler
旧版本(<4.3)
@Override
public void handleReturnValue(Object returnValue, MethodParameter returnType,
ModelAndViewContainer mavContainer, NativeWebRequest webRequest) throws Exception {
if (returnValue == null) {
mavContainer.setRequestHandled(true);
return;
}
DeferredResult<?> deferredResult = (DeferredResult<?>) returnValue;
WebAsyncUtils.getAsyncManager(webRequest).startDeferredResultProcessing(deferredResult, mavContainer);
}
新版本(≥4.3)
@Override
public void handleReturnValue(Object returnValue, MethodParameter returnType,
ModelAndViewContainer mavContainer, NativeWebRequest webRequest) throws Exception {
if (returnValue == null) {
mavContainer.setRequestHandled(true);
return;
}
DeferredResultAdapter adapter = getAdapterFor(returnValue.getClass());
if (adapter == null) {
throw new IllegalStateException(
"Could not find DeferredResultAdapter for return value type: " + returnValue.getClass());
}
DeferredResult<?> result = adapter.adaptToDeferredResult(returnValue);
WebAsyncUtils.getAsyncManager(webRequest).startDeferredResultProcessing(result, mavContainer);
}
这里面添加了对CompletionStage(CompletableFuture)的特殊处理,即将CompletableFuture适配为DeferredResult
@UsesJava8
private static class CompletionStageAdapter implements DeferredResultAdapter {
@Override
public DeferredResult<?> adaptToDeferredResult(Object returnValue) {
Assert.isInstanceOf(CompletionStage.class, returnValue, "CompletionStage expected");
final DeferredResult<Object> result = new DeferredResult<Object>();
@SuppressWarnings("unchecked")
CompletionStage<?> future = (CompletionStage<?>) returnValue;
future.handle(new BiFunction<Object, Throwable, Object>() {
@Override
public Object apply(Object value, Throwable ex) {
if (ex != null) {
result.setErrorResult(ex);
}
else {
result.setResult(value);
}
return null;
}
});
return result;
}
}
但是这里面就会模糊掉(牺牲掉)DeferredResult里面原来有的超时/完成回调这部分的功能。
更新版本(≥5.0)
实现没有变化,只是干掉了adapter接口
else if (returnValue instanceof CompletionStage) {
result = adaptCompletionStage((CompletionStage<?>) returnValue);
}
private DeferredResult<Object> adaptCompletionStage(CompletionStage<?> future) {
DeferredResult<Object> result = new DeferredResult<>();
future.handle((BiFunction<Object, Throwable, Object>) (value, ex) -> {
if (ex != null) {
result.setErrorResult(ex);
}
else {
result.setResult(value);
}
return null;
});
return result;
}
2.spring原生代码
4.3.x增加了对CompletionStage返回值的处理:spring-framework/DeferredResultMethodReturnValueHandler.java at 4.3.x · spring-projects/spring-framework · GitHub
5.0.x删除了DeferredResultAdapter这个接口:spring-framework/DeferredResultMethodReturnValueHandler.java at 5.0.x · spring-projects/spring-framework · GitHub
之前账号冻结了,重新来一遍,原文章地址spring4-3 适配jdk8的CompletableFuture_普通网友的博客-CSDN博客