Consistent nullability for internal field access

This commit is contained in:
Juergen Hoeller
2024-02-28 21:12:57 +01:00
parent e44f84e8ee
commit ce385d136d
2 changed files with 54 additions and 34 deletions

View File

@@ -136,8 +136,8 @@ public final class WebAsyncManager {
}
/**
* Whether the selected handler for the current request chose to handle the
* request asynchronously. A return value of "true" indicates concurrent
* Return whether the selected handler for the current request chose to handle
* the request asynchronously. A return value of "true" indicates concurrent
* handling is under way and the response will remain open. A return value
* of "false" means concurrent handling was either not started or possibly
* that it has completed and the request was dispatched for further
@@ -148,16 +148,16 @@ public final class WebAsyncManager {
}
/**
* Whether a result value exists as a result of concurrent handling.
* Return whether a result value exists as a result of concurrent handling.
*/
public boolean hasConcurrentResult() {
return (this.concurrentResult != RESULT_NONE);
}
/**
* Provides access to the result from concurrent handling.
* Get the result from concurrent handling.
* @return an Object, possibly an {@code Exception} or {@code Throwable} if
* concurrent handling raised one.
* concurrent handling raised one
* @see #clearConcurrentResult()
*/
@Nullable
@@ -166,8 +166,7 @@ public final class WebAsyncManager {
}
/**
* Provides access to additional processing context saved at the start of
* concurrent handling.
* Get the additional processing context saved at the start of concurrent handling.
* @see #clearConcurrentResult()
*/
@Nullable
@@ -208,7 +207,7 @@ public final class WebAsyncManager {
/**
* Register a {@link CallableProcessingInterceptor} without a key.
* The key is derived from the class name and hashcode.
* The key is derived from the class name and hash code.
* @param interceptors one or more interceptors to register
*/
public void registerCallableInterceptors(CallableProcessingInterceptor... interceptors) {
@@ -231,8 +230,8 @@ public final class WebAsyncManager {
}
/**
* Register one or more {@link DeferredResultProcessingInterceptor DeferredResultProcessingInterceptors} without a specified key.
* The default key is derived from the interceptor class name and hash code.
* Register one or more {@link DeferredResultProcessingInterceptor DeferredResultProcessingInterceptors}
* without a specified key. The default key is derived from the interceptor class name and hash code.
* @param interceptors one or more interceptors to register
*/
public void registerDeferredResultInterceptors(DeferredResultProcessingInterceptor... interceptors) {
@@ -298,7 +297,7 @@ public final class WebAsyncManager {
this.taskExecutor = executor;
}
else {
logExecutorWarning();
logExecutorWarning(this.asyncWebRequest);
}
List<CallableProcessingInterceptor> interceptors = new ArrayList<>();
@@ -311,7 +310,7 @@ public final class WebAsyncManager {
this.asyncWebRequest.addTimeoutHandler(() -> {
if (logger.isDebugEnabled()) {
logger.debug("Async request timeout for " + formatRequestUri());
logger.debug("Async request timeout for " + formatUri(this.asyncWebRequest));
}
Object result = interceptorChain.triggerAfterTimeout(this.asyncWebRequest, callable);
if (result != CallableProcessingInterceptor.RESULT_NONE) {
@@ -322,7 +321,7 @@ public final class WebAsyncManager {
this.asyncWebRequest.addErrorHandler(ex -> {
if (!this.errorHandlingInProgress) {
if (logger.isDebugEnabled()) {
logger.debug("Async request error for " + formatRequestUri() + ": " + ex);
logger.debug("Async request error for " + formatUri(this.asyncWebRequest) + ": " + ex);
}
Object result = interceptorChain.triggerAfterError(this.asyncWebRequest, callable, ex);
result = (result != CallableProcessingInterceptor.RESULT_NONE ? result : ex);
@@ -359,7 +358,7 @@ public final class WebAsyncManager {
}
}
private void logExecutorWarning() {
private void logExecutorWarning(AsyncWebRequest asyncWebRequest) {
if (taskExecutorWarning && logger.isWarnEnabled()) {
synchronized (DEFAULT_TASK_EXECUTOR) {
AsyncTaskExecutor executor = this.taskExecutor;
@@ -371,7 +370,7 @@ public final class WebAsyncManager {
"Please, configure a TaskExecutor in the MVC config under \"async support\".\n" +
"The " + executorTypeName + " currently in use is not suitable under load.\n" +
"-------------------------------\n" +
"Request URI: '" + formatRequestUri() + "'\n" +
"Request URI: '" + formatUri(asyncWebRequest) + "'\n" +
"!!!");
taskExecutorWarning = false;
}
@@ -379,11 +378,6 @@ public final class WebAsyncManager {
}
}
private String formatRequestUri() {
HttpServletRequest request = this.asyncWebRequest.getNativeRequest(HttpServletRequest.class);
return request != null ? request.getRequestURI() : "servlet container";
}
private void setConcurrentResultAndDispatch(@Nullable Object result) {
synchronized (WebAsyncManager.this) {
if (this.concurrentResult != RESULT_NONE) {
@@ -393,16 +387,18 @@ public final class WebAsyncManager {
this.errorHandlingInProgress = (result instanceof Throwable);
}
Assert.state(this.asyncWebRequest != null, "AsyncWebRequest must not be null");
if (this.asyncWebRequest.isAsyncComplete()) {
if (logger.isDebugEnabled()) {
logger.debug("Async result set but request already complete: " + formatRequestUri());
logger.debug("Async result set but request already complete: " + formatUri(this.asyncWebRequest));
}
return;
}
if (logger.isDebugEnabled()) {
boolean isError = result instanceof Throwable;
logger.debug("Async " + (isError ? "error" : "result set") + ", dispatch to " + formatRequestUri());
logger.debug("Async " + (isError ? "error" : "result set") +
", dispatch to " + formatUri(this.asyncWebRequest));
}
this.asyncWebRequest.dispatch();
}
@@ -462,8 +458,8 @@ public final class WebAsyncManager {
}
});
this.asyncWebRequest.addCompletionHandler(()
-> interceptorChain.triggerAfterCompletion(this.asyncWebRequest, deferredResult));
this.asyncWebRequest.addCompletionHandler(() ->
interceptorChain.triggerAfterCompletion(this.asyncWebRequest, deferredResult));
interceptorChain.applyBeforeConcurrentHandling(this.asyncWebRequest, deferredResult);
startAsyncProcessing(processingContext);
@@ -486,11 +482,17 @@ public final class WebAsyncManager {
this.concurrentResultContext = processingContext;
this.errorHandlingInProgress = false;
}
this.asyncWebRequest.startAsync();
Assert.state(this.asyncWebRequest != null, "AsyncWebRequest must not be null");
this.asyncWebRequest.startAsync();
if (logger.isDebugEnabled()) {
logger.debug("Started async request");
}
}
private static String formatUri(AsyncWebRequest asyncWebRequest) {
HttpServletRequest request = asyncWebRequest.getNativeRequest(HttpServletRequest.class);
return (request != null ? request.getRequestURI() : "servlet container");
}
}

View File

@@ -1,5 +1,5 @@
/*
* Copyright 2002-2018 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.
@@ -30,6 +30,7 @@ import org.springframework.web.context.request.NativeWebRequest;
*
* @author Rossen Stoyanchev
* @author Juergen Hoeller
* @author Sam Brannen
* @since 3.2
* @param <V> the value type
*/
@@ -37,18 +38,25 @@ public class WebAsyncTask<V> implements BeanFactoryAware {
private final Callable<V> callable;
private Long timeout;
@Nullable
private final Long timeout;
private AsyncTaskExecutor executor;
@Nullable
private final AsyncTaskExecutor executor;
private String executorName;
@Nullable
private final String executorName;
@Nullable
private BeanFactory beanFactory;
@Nullable
private Callable<V> timeoutCallback;
@Nullable
private Callable<V> errorCallback;
@Nullable
private Runnable completionCallback;
@@ -59,6 +67,9 @@ public class WebAsyncTask<V> implements BeanFactoryAware {
public WebAsyncTask(Callable<V> callable) {
Assert.notNull(callable, "Callable must not be null");
this.callable = callable;
this.timeout = null;
this.executor = null;
this.executorName = null;
}
/**
@@ -67,8 +78,11 @@ public class WebAsyncTask<V> implements BeanFactoryAware {
* @param callable the callable for concurrent handling
*/
public WebAsyncTask(long timeout, Callable<V> callable) {
this(callable);
Assert.notNull(callable, "Callable must not be null");
this.callable = callable;
this.timeout = timeout;
this.executor = null;
this.executorName = null;
}
/**
@@ -78,10 +92,12 @@ public class WebAsyncTask<V> implements BeanFactoryAware {
* @param callable the callable for concurrent handling
*/
public WebAsyncTask(@Nullable Long timeout, String executorName, Callable<V> callable) {
this(callable);
Assert.notNull(callable, "Callable must not be null");
Assert.notNull(executorName, "Executor name must not be null");
this.executorName = executorName;
this.callable = callable;
this.timeout = timeout;
this.executor = null;
this.executorName = executorName;
}
/**
@@ -91,10 +107,12 @@ public class WebAsyncTask<V> implements BeanFactoryAware {
* @param callable the callable for concurrent handling
*/
public WebAsyncTask(@Nullable Long timeout, AsyncTaskExecutor executor, Callable<V> callable) {
this(callable);
Assert.notNull(callable, "Callable must not be null");
Assert.notNull(executor, "Executor must not be null");
this.executor = executor;
this.callable = callable;
this.timeout = timeout;
this.executor = executor;
this.executorName = null;
}