Skip to content

Commit ce385d1

Browse files
committed
Consistent nullability for internal field access
1 parent e44f84e commit ce385d1

File tree

2 files changed

+54
-34
lines changed

2 files changed

+54
-34
lines changed

spring-web/src/main/java/org/springframework/web/context/request/async/WebAsyncManager.java

Lines changed: 27 additions & 25 deletions
Original file line numberDiff line numberDiff line change
@@ -136,8 +136,8 @@ public void setTaskExecutor(AsyncTaskExecutor taskExecutor) {
136136
}
137137

138138
/**
139-
* Whether the selected handler for the current request chose to handle the
140-
* request asynchronously. A return value of "true" indicates concurrent
139+
* Return whether the selected handler for the current request chose to handle
140+
* the request asynchronously. A return value of "true" indicates concurrent
141141
* handling is under way and the response will remain open. A return value
142142
* of "false" means concurrent handling was either not started or possibly
143143
* that it has completed and the request was dispatched for further
@@ -148,16 +148,16 @@ public boolean isConcurrentHandlingStarted() {
148148
}
149149

150150
/**
151-
* Whether a result value exists as a result of concurrent handling.
151+
* Return whether a result value exists as a result of concurrent handling.
152152
*/
153153
public boolean hasConcurrentResult() {
154154
return (this.concurrentResult != RESULT_NONE);
155155
}
156156

157157
/**
158-
* Provides access to the result from concurrent handling.
158+
* Get the result from concurrent handling.
159159
* @return an Object, possibly an {@code Exception} or {@code Throwable} if
160-
* concurrent handling raised one.
160+
* concurrent handling raised one
161161
* @see #clearConcurrentResult()
162162
*/
163163
@Nullable
@@ -166,8 +166,7 @@ public Object getConcurrentResult() {
166166
}
167167

168168
/**
169-
* Provides access to additional processing context saved at the start of
170-
* concurrent handling.
169+
* Get the additional processing context saved at the start of concurrent handling.
171170
* @see #clearConcurrentResult()
172171
*/
173172
@Nullable
@@ -208,7 +207,7 @@ public void registerCallableInterceptor(Object key, CallableProcessingIntercepto
208207

209208
/**
210209
* Register a {@link CallableProcessingInterceptor} without a key.
211-
* The key is derived from the class name and hashcode.
210+
* The key is derived from the class name and hash code.
212211
* @param interceptors one or more interceptors to register
213212
*/
214213
public void registerCallableInterceptors(CallableProcessingInterceptor... interceptors) {
@@ -231,8 +230,8 @@ public void registerDeferredResultInterceptor(Object key, DeferredResultProcessi
231230
}
232231

233232
/**
234-
* Register one or more {@link DeferredResultProcessingInterceptor DeferredResultProcessingInterceptors} without a specified key.
235-
* The default key is derived from the interceptor class name and hash code.
233+
* Register one or more {@link DeferredResultProcessingInterceptor DeferredResultProcessingInterceptors}
234+
* without a specified key. The default key is derived from the interceptor class name and hash code.
236235
* @param interceptors one or more interceptors to register
237236
*/
238237
public void registerDeferredResultInterceptors(DeferredResultProcessingInterceptor... interceptors) {
@@ -298,7 +297,7 @@ public void startCallableProcessing(final WebAsyncTask<?> webAsyncTask, Object..
298297
this.taskExecutor = executor;
299298
}
300299
else {
301-
logExecutorWarning();
300+
logExecutorWarning(this.asyncWebRequest);
302301
}
303302

304303
List<CallableProcessingInterceptor> interceptors = new ArrayList<>();
@@ -311,7 +310,7 @@ public void startCallableProcessing(final WebAsyncTask<?> webAsyncTask, Object..
311310

312311
this.asyncWebRequest.addTimeoutHandler(() -> {
313312
if (logger.isDebugEnabled()) {
314-
logger.debug("Async request timeout for " + formatRequestUri());
313+
logger.debug("Async request timeout for " + formatUri(this.asyncWebRequest));
315314
}
316315
Object result = interceptorChain.triggerAfterTimeout(this.asyncWebRequest, callable);
317316
if (result != CallableProcessingInterceptor.RESULT_NONE) {
@@ -322,7 +321,7 @@ public void startCallableProcessing(final WebAsyncTask<?> webAsyncTask, Object..
322321
this.asyncWebRequest.addErrorHandler(ex -> {
323322
if (!this.errorHandlingInProgress) {
324323
if (logger.isDebugEnabled()) {
325-
logger.debug("Async request error for " + formatRequestUri() + ": " + ex);
324+
logger.debug("Async request error for " + formatUri(this.asyncWebRequest) + ": " + ex);
326325
}
327326
Object result = interceptorChain.triggerAfterError(this.asyncWebRequest, callable, ex);
328327
result = (result != CallableProcessingInterceptor.RESULT_NONE ? result : ex);
@@ -359,7 +358,7 @@ public void startCallableProcessing(final WebAsyncTask<?> webAsyncTask, Object..
359358
}
360359
}
361360

362-
private void logExecutorWarning() {
361+
private void logExecutorWarning(AsyncWebRequest asyncWebRequest) {
363362
if (taskExecutorWarning && logger.isWarnEnabled()) {
364363
synchronized (DEFAULT_TASK_EXECUTOR) {
365364
AsyncTaskExecutor executor = this.taskExecutor;
@@ -371,19 +370,14 @@ private void logExecutorWarning() {
371370
"Please, configure a TaskExecutor in the MVC config under \"async support\".\n" +
372371
"The " + executorTypeName + " currently in use is not suitable under load.\n" +
373372
"-------------------------------\n" +
374-
"Request URI: '" + formatRequestUri() + "'\n" +
373+
"Request URI: '" + formatUri(asyncWebRequest) + "'\n" +
375374
"!!!");
376375
taskExecutorWarning = false;
377376
}
378377
}
379378
}
380379
}
381380

382-
private String formatRequestUri() {
383-
HttpServletRequest request = this.asyncWebRequest.getNativeRequest(HttpServletRequest.class);
384-
return request != null ? request.getRequestURI() : "servlet container";
385-
}
386-
387381
private void setConcurrentResultAndDispatch(@Nullable Object result) {
388382
synchronized (WebAsyncManager.this) {
389383
if (this.concurrentResult != RESULT_NONE) {
@@ -393,16 +387,18 @@ private void setConcurrentResultAndDispatch(@Nullable Object result) {
393387
this.errorHandlingInProgress = (result instanceof Throwable);
394388
}
395389

390+
Assert.state(this.asyncWebRequest != null, "AsyncWebRequest must not be null");
396391
if (this.asyncWebRequest.isAsyncComplete()) {
397392
if (logger.isDebugEnabled()) {
398-
logger.debug("Async result set but request already complete: " + formatRequestUri());
393+
logger.debug("Async result set but request already complete: " + formatUri(this.asyncWebRequest));
399394
}
400395
return;
401396
}
402397

403398
if (logger.isDebugEnabled()) {
404399
boolean isError = result instanceof Throwable;
405-
logger.debug("Async " + (isError ? "error" : "result set") + ", dispatch to " + formatRequestUri());
400+
logger.debug("Async " + (isError ? "error" : "result set") +
401+
", dispatch to " + formatUri(this.asyncWebRequest));
406402
}
407403
this.asyncWebRequest.dispatch();
408404
}
@@ -462,8 +458,8 @@ public void startDeferredResultProcessing(
462458
}
463459
});
464460

465-
this.asyncWebRequest.addCompletionHandler(()
466-
-> interceptorChain.triggerAfterCompletion(this.asyncWebRequest, deferredResult));
461+
this.asyncWebRequest.addCompletionHandler(() ->
462+
interceptorChain.triggerAfterCompletion(this.asyncWebRequest, deferredResult));
467463

468464
interceptorChain.applyBeforeConcurrentHandling(this.asyncWebRequest, deferredResult);
469465
startAsyncProcessing(processingContext);
@@ -486,11 +482,17 @@ private void startAsyncProcessing(Object[] processingContext) {
486482
this.concurrentResultContext = processingContext;
487483
this.errorHandlingInProgress = false;
488484
}
489-
this.asyncWebRequest.startAsync();
490485

486+
Assert.state(this.asyncWebRequest != null, "AsyncWebRequest must not be null");
487+
this.asyncWebRequest.startAsync();
491488
if (logger.isDebugEnabled()) {
492489
logger.debug("Started async request");
493490
}
494491
}
495492

493+
private static String formatUri(AsyncWebRequest asyncWebRequest) {
494+
HttpServletRequest request = asyncWebRequest.getNativeRequest(HttpServletRequest.class);
495+
return (request != null ? request.getRequestURI() : "servlet container");
496+
}
497+
496498
}

spring-web/src/main/java/org/springframework/web/context/request/async/WebAsyncTask.java

Lines changed: 27 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
/*
2-
* Copyright 2002-2018 the original author or authors.
2+
* Copyright 2002-2024 the original author or authors.
33
*
44
* Licensed under the Apache License, Version 2.0 (the "License");
55
* you may not use this file except in compliance with the License.
@@ -30,25 +30,33 @@
3030
*
3131
* @author Rossen Stoyanchev
3232
* @author Juergen Hoeller
33+
* @author Sam Brannen
3334
* @since 3.2
3435
* @param <V> the value type
3536
*/
3637
public class WebAsyncTask<V> implements BeanFactoryAware {
3738

3839
private final Callable<V> callable;
3940

40-
private Long timeout;
41+
@Nullable
42+
private final Long timeout;
4143

42-
private AsyncTaskExecutor executor;
44+
@Nullable
45+
private final AsyncTaskExecutor executor;
4346

44-
private String executorName;
47+
@Nullable
48+
private final String executorName;
4549

50+
@Nullable
4651
private BeanFactory beanFactory;
4752

53+
@Nullable
4854
private Callable<V> timeoutCallback;
4955

56+
@Nullable
5057
private Callable<V> errorCallback;
5158

59+
@Nullable
5260
private Runnable completionCallback;
5361

5462

@@ -59,6 +67,9 @@ public class WebAsyncTask<V> implements BeanFactoryAware {
5967
public WebAsyncTask(Callable<V> callable) {
6068
Assert.notNull(callable, "Callable must not be null");
6169
this.callable = callable;
70+
this.timeout = null;
71+
this.executor = null;
72+
this.executorName = null;
6273
}
6374

6475
/**
@@ -67,8 +78,11 @@ public WebAsyncTask(Callable<V> callable) {
6778
* @param callable the callable for concurrent handling
6879
*/
6980
public WebAsyncTask(long timeout, Callable<V> callable) {
70-
this(callable);
81+
Assert.notNull(callable, "Callable must not be null");
82+
this.callable = callable;
7183
this.timeout = timeout;
84+
this.executor = null;
85+
this.executorName = null;
7286
}
7387

7488
/**
@@ -78,10 +92,12 @@ public WebAsyncTask(long timeout, Callable<V> callable) {
7892
* @param callable the callable for concurrent handling
7993
*/
8094
public WebAsyncTask(@Nullable Long timeout, String executorName, Callable<V> callable) {
81-
this(callable);
95+
Assert.notNull(callable, "Callable must not be null");
8296
Assert.notNull(executorName, "Executor name must not be null");
83-
this.executorName = executorName;
97+
this.callable = callable;
8498
this.timeout = timeout;
99+
this.executor = null;
100+
this.executorName = executorName;
85101
}
86102

87103
/**
@@ -91,10 +107,12 @@ public WebAsyncTask(@Nullable Long timeout, String executorName, Callable<V> cal
91107
* @param callable the callable for concurrent handling
92108
*/
93109
public WebAsyncTask(@Nullable Long timeout, AsyncTaskExecutor executor, Callable<V> callable) {
94-
this(callable);
110+
Assert.notNull(callable, "Callable must not be null");
95111
Assert.notNull(executor, "Executor must not be null");
96-
this.executor = executor;
112+
this.callable = callable;
97113
this.timeout = timeout;
114+
this.executor = executor;
115+
this.executorName = null;
98116
}
99117

100118

0 commit comments

Comments
 (0)