public final class WebAsyncManager
extends java.lang.Object
An async scenario starts with request processing as usual in a thread (T1).
Concurrent request handling can be initiated by calling
startCallableProcessing
or
startDeferredResultProcessing
,
both of which produce a result in a separate thread (T2). The result is saved
and the request dispatched to the container, to resume processing with the saved
result in a third thread (T3). Within the dispatched thread (T3), the saved
result can be accessed via getConcurrentResult()
or its presence
detected via hasConcurrentResult()
.
AsyncWebRequestInterceptor
,
AsyncHandlerInterceptor
,
OncePerRequestFilter.shouldNotFilterAsyncDispatch()
,
OncePerRequestFilter.isAsyncDispatch(HttpServletRequest)
Modifier and Type | Field and Description |
---|---|
private AsyncWebRequest |
asyncWebRequest |
private java.util.Map<java.lang.Object,CallableProcessingInterceptor> |
callableInterceptors |
private java.lang.Object |
concurrentResult |
private java.lang.Object[] |
concurrentResultContext |
private java.util.Map<java.lang.Object,DeferredResultProcessingInterceptor> |
deferredResultInterceptors |
private static Log |
logger |
private static java.lang.Object |
RESULT_NONE |
private AsyncTaskExecutor |
taskExecutor |
private static CallableProcessingInterceptor |
timeoutCallableInterceptor |
private static DeferredResultProcessingInterceptor |
timeoutDeferredResultInterceptor |
private static UrlPathHelper |
urlPathHelper |
Constructor and Description |
---|
WebAsyncManager()
Package-private constructor.
|
Modifier and Type | Method and Description |
---|---|
void |
clearConcurrentResult()
Clear concurrentResult and
concurrentResultContext.
|
CallableProcessingInterceptor |
getCallableInterceptor(java.lang.Object key)
Get the
CallableProcessingInterceptor registered under the given key. |
java.lang.Object |
getConcurrentResult()
Provides access to the result from concurrent handling.
|
java.lang.Object[] |
getConcurrentResultContext()
Provides access to additional processing context saved at the start of
concurrent handling.
|
DeferredResultProcessingInterceptor |
getDeferredResultInterceptor(java.lang.Object key)
Get the
DeferredResultProcessingInterceptor registered under the given key. |
boolean |
hasConcurrentResult()
Whether a result value exists as a result of concurrent handling.
|
boolean |
isConcurrentHandlingStarted()
Whether the selected handler for the current request chose to handle the
request asynchronously.
|
void |
registerCallableInterceptor(java.lang.Object key,
CallableProcessingInterceptor interceptor)
Register a
CallableProcessingInterceptor under the given key. |
void |
registerCallableInterceptors(CallableProcessingInterceptor... interceptors)
Register a
CallableProcessingInterceptor without a key. |
void |
registerDeferredResultInterceptor(java.lang.Object key,
DeferredResultProcessingInterceptor interceptor)
Register a
DeferredResultProcessingInterceptor under the given key. |
void |
registerDeferredResultInterceptors(DeferredResultProcessingInterceptor... interceptors)
Register one or more
DeferredResultProcessingInterceptor s without a specified key. |
void |
setAsyncWebRequest(AsyncWebRequest asyncWebRequest)
Configure the
AsyncWebRequest to use. |
private void |
setConcurrentResultAndDispatch(java.lang.Object result) |
void |
setTaskExecutor(AsyncTaskExecutor taskExecutor)
Configure an AsyncTaskExecutor for use with concurrent processing via
startCallableProcessing(Callable, Object...) . |
private void |
startAsyncProcessing(java.lang.Object[] processingContext) |
void |
startCallableProcessing(java.util.concurrent.Callable<?> callable,
java.lang.Object... processingContext)
Start concurrent request processing and execute the given task with an
AsyncTaskExecutor . |
void |
startCallableProcessing(WebAsyncTask<?> webAsyncTask,
java.lang.Object... processingContext)
Use the given
WebAsyncTask to configure the task executor as well as
the timeout value of the AsyncWebRequest before delegating to
startCallableProcessing(Callable, Object...) . |
void |
startDeferredResultProcessing(DeferredResult<?> deferredResult,
java.lang.Object... processingContext)
Start concurrent request processing and initialize the given
DeferredResult with a DeferredResult.DeferredResultHandler that saves
the result and dispatches the request to resume processing of that
result. |
private static final java.lang.Object RESULT_NONE
private static final Log logger
private static final UrlPathHelper urlPathHelper
private static final CallableProcessingInterceptor timeoutCallableInterceptor
private static final DeferredResultProcessingInterceptor timeoutDeferredResultInterceptor
private AsyncWebRequest asyncWebRequest
private AsyncTaskExecutor taskExecutor
private java.lang.Object concurrentResult
private java.lang.Object[] concurrentResultContext
private final java.util.Map<java.lang.Object,CallableProcessingInterceptor> callableInterceptors
private final java.util.Map<java.lang.Object,DeferredResultProcessingInterceptor> deferredResultInterceptors
WebAsyncManager()
WebAsyncUtils#getAsyncManager(javax.servlet.ServletRequest)
,
WebAsyncUtils#getAsyncManager(org.springframework.web.context.request.WebRequest)
public void setAsyncWebRequest(AsyncWebRequest asyncWebRequest)
AsyncWebRequest
to use. This property may be set
more than once during a single request to accurately reflect the current
state of the request (e.g. following a forward, request/response
wrapping, etc). However, it should not be set while concurrent handling
is in progress, i.e. while isConcurrentHandlingStarted()
is
true
.asyncWebRequest
- the web request to usepublic void setTaskExecutor(AsyncTaskExecutor taskExecutor)
startCallableProcessing(Callable, Object...)
.
By default a SimpleAsyncTaskExecutor
instance is used.
public boolean isConcurrentHandlingStarted()
public boolean hasConcurrentResult()
public java.lang.Object getConcurrentResult()
Exception
or Throwable
if
concurrent handling raised one.clearConcurrentResult()
public java.lang.Object[] getConcurrentResultContext()
clearConcurrentResult()
public CallableProcessingInterceptor getCallableInterceptor(java.lang.Object key)
CallableProcessingInterceptor
registered under the given key.key
- the keynull
public DeferredResultProcessingInterceptor getDeferredResultInterceptor(java.lang.Object key)
DeferredResultProcessingInterceptor
registered under the given key.key
- the keynull
public void registerCallableInterceptor(java.lang.Object key, CallableProcessingInterceptor interceptor)
CallableProcessingInterceptor
under the given key.key
- the keyinterceptor
- the interceptor to registerpublic void registerCallableInterceptors(CallableProcessingInterceptor... interceptors)
CallableProcessingInterceptor
without a key.
The key is derived from the class name and hashcode.interceptors
- one or more interceptors to registerpublic void registerDeferredResultInterceptor(java.lang.Object key, DeferredResultProcessingInterceptor interceptor)
DeferredResultProcessingInterceptor
under the given key.key
- the keyinterceptor
- the interceptor to registerpublic void registerDeferredResultInterceptors(DeferredResultProcessingInterceptor... interceptors)
DeferredResultProcessingInterceptor
s without a specified key.
The default key is derived from the interceptor class name and hash code.interceptors
- one or more interceptors to registerpublic void clearConcurrentResult()
public void startCallableProcessing(java.util.concurrent.Callable<?> callable, java.lang.Object... processingContext) throws java.lang.Exception
AsyncTaskExecutor
. The result
from the task execution is saved and the request dispatched in order to
resume processing of that result. If the task raises an Exception then
the saved result will be the raised Exception.callable
- a unit of work to be executed asynchronouslyprocessingContext
- additional context to save that can be accessed
via getConcurrentResultContext()
java.lang.Exception
- if concurrent processing failed to startgetConcurrentResult()
,
getConcurrentResultContext()
public void startCallableProcessing(WebAsyncTask<?> webAsyncTask, java.lang.Object... processingContext) throws java.lang.Exception
WebAsyncTask
to configure the task executor as well as
the timeout value of the AsyncWebRequest
before delegating to
startCallableProcessing(Callable, Object...)
.webAsyncTask
- a WebAsyncTask containing the target Callable
processingContext
- additional context to save that can be accessed
via getConcurrentResultContext()
java.lang.Exception
- if concurrent processing failed to startprivate void setConcurrentResultAndDispatch(java.lang.Object result)
public void startDeferredResultProcessing(DeferredResult<?> deferredResult, java.lang.Object... processingContext) throws java.lang.Exception
DeferredResult
with a DeferredResult.DeferredResultHandler
that saves
the result and dispatches the request to resume processing of that
result. The AsyncWebRequest
is also updated with a completion
handler that expires the DeferredResult
and a timeout handler
assuming the DeferredResult
has a default timeout result.deferredResult
- the DeferredResult instance to initializeprocessingContext
- additional context to save that can be accessed
via getConcurrentResultContext()
java.lang.Exception
- if concurrent processing failed to startgetConcurrentResult()
,
getConcurrentResultContext()
private void startAsyncProcessing(java.lang.Object[] processingContext)