spring4-3 适配jdk8的CompletableFuture
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返回值的处理:
5.0.x删除了DeferredResultAdapter这个接口: