Consistent nullability for concurrent result

(cherry picked from commit b92877990d)
This commit is contained in:
Juergen Hoeller
2024-01-24 11:43:36 +01:00
parent f22bdf4734
commit 7ac66eff4d
3 changed files with 18 additions and 9 deletions

View File

@@ -1,5 +1,5 @@
/*
* Copyright 2002-2022 the original author or authors.
* Copyright 2002-2024 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.
@@ -53,6 +53,7 @@ import org.springframework.web.context.request.async.DeferredResult.DeferredResu
*
* @author Rossen Stoyanchev
* @author Juergen Hoeller
* @author Sam Brannen
* @since 3.2
* @see org.springframework.web.context.request.AsyncWebRequestInterceptor
* @see org.springframework.web.servlet.AsyncHandlerInterceptor
@@ -77,12 +78,15 @@ public final class WebAsyncManager {
private static Boolean taskExecutorWarning = true;
@Nullable
private AsyncWebRequest asyncWebRequest;
private AsyncTaskExecutor taskExecutor = DEFAULT_TASK_EXECUTOR;
@Nullable
private volatile Object concurrentResult = RESULT_NONE;
@Nullable
private volatile Object[] concurrentResultContext;
/*
@@ -156,6 +160,7 @@ public final class WebAsyncManager {
* concurrent handling raised one.
* @see #clearConcurrentResult()
*/
@Nullable
public Object getConcurrentResult() {
return this.concurrentResult;
}
@@ -165,6 +170,7 @@ public final class WebAsyncManager {
* concurrent handling.
* @see #clearConcurrentResult()
*/
@Nullable
public Object[] getConcurrentResultContext() {
return this.concurrentResultContext;
}
@@ -378,7 +384,7 @@ public final class WebAsyncManager {
return request != null ? request.getRequestURI() : "servlet container";
}
private void setConcurrentResultAndDispatch(Object result) {
private void setConcurrentResultAndDispatch(@Nullable Object result) {
synchronized (WebAsyncManager.this) {
if (this.concurrentResult != RESULT_NONE) {
return;

View File

@@ -1,5 +1,5 @@
/*
* Copyright 2002-2020 the original author or authors.
* Copyright 2002-2024 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.
@@ -50,6 +50,7 @@ import org.springframework.http.converter.support.AllEncompassingFormHttpMessage
import org.springframework.http.converter.xml.SourceHttpMessageConverter;
import org.springframework.lang.Nullable;
import org.springframework.ui.ModelMap;
import org.springframework.util.Assert;
import org.springframework.util.CollectionUtils;
import org.springframework.util.ReflectionUtils.MethodFilter;
import org.springframework.web.accept.ContentNegotiationManager;
@@ -465,7 +466,7 @@ public class RequestMappingHandlerAdapter extends AbstractHandlerMethodAdapter
}
/**
* By default the content of the "default" model is used both during
* By default, the content of the "default" model is used both during
* rendering and redirect scenarios. Alternatively a controller method
* can declare a {@link RedirectAttributes} argument and use it to provide
* attributes for a redirect.
@@ -883,7 +884,9 @@ public class RequestMappingHandlerAdapter extends AbstractHandlerMethodAdapter
if (asyncManager.hasConcurrentResult()) {
Object result = asyncManager.getConcurrentResult();
mavContainer = (ModelAndViewContainer) asyncManager.getConcurrentResultContext()[0];
Object[] resultContext = asyncManager.getConcurrentResultContext();
Assert.state(resultContext != null && resultContext.length > 0, "Missing result context");
mavContainer = (ModelAndViewContainer) resultContext[0];
asyncManager.clearConcurrentResult();
LogFormatUtils.traceDebug(logger, traceOn -> {
String formatted = LogFormatUtils.formatValue(result, !traceOn);

View File

@@ -1,5 +1,5 @@
/*
* Copyright 2002-2021 the original author or authors.
* Copyright 2002-2024 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.
@@ -199,7 +199,7 @@ public class ServletInvocableHandlerMethod extends InvocableHandlerMethod {
* actually invoking the controller method. This is useful when processing
* async return values (e.g. Callable, DeferredResult, ListenableFuture).
*/
ServletInvocableHandlerMethod wrapConcurrentResult(Object result) {
ServletInvocableHandlerMethod wrapConcurrentResult(@Nullable Object result) {
return new ConcurrentResultHandlerMethod(result, new ConcurrentResultMethodParameter(result));
}
@@ -214,7 +214,7 @@ public class ServletInvocableHandlerMethod extends InvocableHandlerMethod {
private final MethodParameter returnType;
public ConcurrentResultHandlerMethod(final Object result, ConcurrentResultMethodParameter returnType) {
public ConcurrentResultHandlerMethod(@Nullable Object result, ConcurrentResultMethodParameter returnType) {
super((Callable<Object>) () -> {
if (result instanceof Exception) {
throw (Exception) result;
@@ -278,7 +278,7 @@ public class ServletInvocableHandlerMethod extends InvocableHandlerMethod {
private final ResolvableType returnType;
public ConcurrentResultMethodParameter(Object returnValue) {
public ConcurrentResultMethodParameter(@Nullable Object returnValue) {
super(-1);
this.returnValue = returnValue;
this.returnType = (returnValue instanceof ReactiveTypeHandler.CollectedValuesList ?