From 9a6f636e17dc67512debc132eaed29acb721af41 Mon Sep 17 00:00:00 2001 From: Juergen Hoeller Date: Sat, 24 Feb 2024 08:21:37 +0100 Subject: [PATCH] Consistent nullability for internal field access --- .../request/async/WebAsyncManager.java | 48 ++++++++++--------- .../context/request/async/WebAsyncTask.java | 6 ++- 2 files changed, 30 insertions(+), 24 deletions(-) diff --git a/spring-web/src/main/java/org/springframework/web/context/request/async/WebAsyncManager.java b/spring-web/src/main/java/org/springframework/web/context/request/async/WebAsyncManager.java index 220996ee70..a94fbd3900 100644 --- a/spring-web/src/main/java/org/springframework/web/context/request/async/WebAsyncManager.java +++ b/spring-web/src/main/java/org/springframework/web/context/request/async/WebAsyncManager.java @@ -135,8 +135,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 @@ -147,16 +147,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 @@ -165,8 +165,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 @@ -207,7 +206,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) { @@ -230,8 +229,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) { @@ -297,7 +296,7 @@ public final class WebAsyncManager { this.taskExecutor = executor; } else { - logExecutorWarning(); + logExecutorWarning(this.asyncWebRequest); } List interceptors = new ArrayList<>(); @@ -310,7 +309,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) { @@ -321,7 +320,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); @@ -358,7 +357,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; @@ -370,7 +369,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; } @@ -378,11 +377,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) { @@ -392,16 +386,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(); } @@ -485,11 +481,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"); + } + } diff --git a/spring-web/src/main/java/org/springframework/web/context/request/async/WebAsyncTask.java b/spring-web/src/main/java/org/springframework/web/context/request/async/WebAsyncTask.java index d105446bf3..5b49b79d46 100644 --- a/spring-web/src/main/java/org/springframework/web/context/request/async/WebAsyncTask.java +++ b/spring-web/src/main/java/org/springframework/web/context/request/async/WebAsyncTask.java @@ -1,5 +1,5 @@ /* - * Copyright 2002-2023 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. @@ -47,12 +47,16 @@ public class WebAsyncTask implements BeanFactoryAware { @Nullable private final String executorName; + @Nullable private BeanFactory beanFactory; + @Nullable private Callable timeoutCallback; + @Nullable private Callable errorCallback; + @Nullable private Runnable completionCallback;