Add async options to MVC namespace and Java config
The MVC Java config method to implement is WebMvcConfigurer.configureAsyncSupport(AsyncSupportConfigurer) The MVC namespace element is: <mvc:annotation-driven> <mvc:async-support default-timeout="2500" task-executor="myExecutor" /> </mvc:annotation-driven> Issue: SPR-9694
This commit is contained in:
@@ -174,6 +174,8 @@ class AnnotationDrivenBeanDefinitionParser implements BeanDefinitionParser {
|
||||
ManagedList<?> messageConverters = getMessageConverters(element, source, parserContext);
|
||||
ManagedList<?> argumentResolvers = getArgumentResolvers(element, source, parserContext);
|
||||
ManagedList<?> returnValueHandlers = getReturnValueHandlers(element, source, parserContext);
|
||||
String asyncTimeout = getAsyncTimeout(element, source, parserContext);
|
||||
RuntimeBeanReference asyncExecutor = getAsyncExecutor(element, source, parserContext);
|
||||
|
||||
RootBeanDefinition handlerAdapterDef = new RootBeanDefinition(RequestMappingHandlerAdapter.class);
|
||||
handlerAdapterDef.setSource(source);
|
||||
@@ -191,6 +193,12 @@ class AnnotationDrivenBeanDefinitionParser implements BeanDefinitionParser {
|
||||
if (returnValueHandlers != null) {
|
||||
handlerAdapterDef.getPropertyValues().add("customReturnValueHandlers", returnValueHandlers);
|
||||
}
|
||||
if (asyncTimeout != null) {
|
||||
handlerAdapterDef.getPropertyValues().add("asyncRequestTimeout", asyncTimeout);
|
||||
}
|
||||
if (asyncExecutor != null) {
|
||||
handlerAdapterDef.getPropertyValues().add("taskExecutor", asyncExecutor);
|
||||
}
|
||||
String handlerAdapterName = parserContext.getReaderContext().registerWithGeneratedName(handlerAdapterDef);
|
||||
|
||||
RootBeanDefinition csInterceptorDef = new RootBeanDefinition(ConversionServiceExposingInterceptor.class);
|
||||
@@ -318,6 +326,21 @@ class AnnotationDrivenBeanDefinitionParser implements BeanDefinitionParser {
|
||||
}
|
||||
}
|
||||
|
||||
private String getAsyncTimeout(Element element, Object source, ParserContext parserContext) {
|
||||
Element asyncElement = DomUtils.getChildElementByTagName(element, "async-support");
|
||||
return (asyncElement != null) ? asyncElement.getAttribute("default-timeout") : null;
|
||||
}
|
||||
|
||||
private RuntimeBeanReference getAsyncExecutor(Element element, Object source, ParserContext parserContext) {
|
||||
Element asyncElement = DomUtils.getChildElementByTagName(element, "async-support");
|
||||
if (asyncElement != null) {
|
||||
if (asyncElement.hasAttribute("task-executor")) {
|
||||
return new RuntimeBeanReference(asyncElement.getAttribute("task-executor"));
|
||||
}
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
private ManagedList<?> getArgumentResolvers(Element element, Object source, ParserContext parserContext) {
|
||||
Element resolversElement = DomUtils.getChildElementByTagName(element, "argument-resolvers");
|
||||
if (resolversElement != null) {
|
||||
|
||||
@@ -0,0 +1,75 @@
|
||||
/*
|
||||
* Copyright 2002-2012 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.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
package org.springframework.web.servlet.config.annotation;
|
||||
|
||||
import java.util.concurrent.Callable;
|
||||
|
||||
import org.springframework.core.task.AsyncTaskExecutor;
|
||||
import org.springframework.core.task.SimpleAsyncTaskExecutor;
|
||||
import org.springframework.web.context.request.async.AsyncTask;
|
||||
|
||||
/**
|
||||
* Helps with configuring a options for asynchronous request processing.
|
||||
*
|
||||
* @author Rossen Stoyanchev
|
||||
* @since 3.2
|
||||
*/
|
||||
public class AsyncSupportConfigurer {
|
||||
|
||||
private AsyncTaskExecutor taskExecutor;
|
||||
|
||||
private Long timeout;
|
||||
|
||||
/**
|
||||
* Set the default {@link AsyncTaskExecutor} to use when a controller method
|
||||
* returns a {@link Callable}. Controller methods can override this default on
|
||||
* a per-request basis by returning an {@link AsyncTask}.
|
||||
*
|
||||
* <p>By default a {@link SimpleAsyncTaskExecutor} instance is used and it's
|
||||
* highly recommended to change that default in production since the simple
|
||||
* executor does not re-use threads.
|
||||
*
|
||||
* @param taskExecutor the task executor instance to use by default
|
||||
*/
|
||||
public AsyncSupportConfigurer setTaskExecutor(AsyncTaskExecutor taskExecutor) {
|
||||
this.taskExecutor = taskExecutor;
|
||||
return this;
|
||||
}
|
||||
|
||||
/**
|
||||
* Specify the amount of time, in milliseconds, before asynchronous request
|
||||
* handling times out. In Servlet 3, the timeout begins after the main request
|
||||
* processing thread has exited and ends when the request is dispatched again
|
||||
* for further processing of the concurrently produced result.
|
||||
* <p>If this value is not set, the default timeout of the underlying
|
||||
* implementation is used, e.g. 10 seconds on Tomcat with Servlet 3.
|
||||
*
|
||||
* @param timeout the timeout value in milliseconds
|
||||
*/
|
||||
public AsyncSupportConfigurer setDefaultTimeout(long timeout) {
|
||||
this.timeout = timeout;
|
||||
return this;
|
||||
}
|
||||
|
||||
protected AsyncTaskExecutor getTaskExecutor() {
|
||||
return this.taskExecutor;
|
||||
}
|
||||
|
||||
protected Long getTimeout() {
|
||||
return this.timeout;
|
||||
}
|
||||
|
||||
}
|
||||
@@ -60,6 +60,11 @@ public class DelegatingWebMvcConfiguration extends WebMvcConfigurationSupport {
|
||||
this.configurers.configureContentNegotiation(configurer);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void configureAsyncSupport(AsyncSupportConfigurer configurer) {
|
||||
this.configurers.configureAsyncSupport(configurer);
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void addViewControllers(ViewControllerRegistry registry) {
|
||||
this.configurers.addViewControllers(registry);
|
||||
|
||||
@@ -354,6 +354,17 @@ public class WebMvcConfigurationSupport implements ApplicationContextAware, Serv
|
||||
adapter.setWebBindingInitializer(webBindingInitializer);
|
||||
adapter.setCustomArgumentResolvers(argumentResolvers);
|
||||
adapter.setCustomReturnValueHandlers(returnValueHandlers);
|
||||
|
||||
AsyncSupportConfigurer configurer = new AsyncSupportConfigurer();
|
||||
configureAsyncSupport(configurer);
|
||||
|
||||
if (configurer.getTaskExecutor() != null) {
|
||||
adapter.setTaskExecutor(configurer.getTaskExecutor());
|
||||
}
|
||||
if (configurer.getTimeout() != null) {
|
||||
adapter.setAsyncRequestTimeout(configurer.getTimeout());
|
||||
}
|
||||
|
||||
return adapter;
|
||||
}
|
||||
|
||||
@@ -516,6 +527,13 @@ public class WebMvcConfigurationSupport implements ApplicationContextAware, Serv
|
||||
protected void addFormatters(FormatterRegistry registry) {
|
||||
}
|
||||
|
||||
/**
|
||||
* Override this method to configure asynchronous request processing options.
|
||||
* @see AsyncSupportConfigurer
|
||||
*/
|
||||
public void configureAsyncSupport(AsyncSupportConfigurer configurer) {
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns a {@link HttpRequestHandlerAdapter} for processing requests
|
||||
* with {@link HttpRequestHandler}s.
|
||||
|
||||
@@ -74,6 +74,11 @@ public interface WebMvcConfigurer {
|
||||
*/
|
||||
void configureContentNegotiation(ContentNegotiationConfigurer configurer);
|
||||
|
||||
/**
|
||||
* Configure asynchronous request handling options.
|
||||
*/
|
||||
void configureAsyncSupport(AsyncSupportConfigurer configurer);
|
||||
|
||||
/**
|
||||
* Add resolvers to support custom controller method argument types.
|
||||
* <p>This does not override the built-in support for resolving handler
|
||||
|
||||
@@ -64,6 +64,13 @@ public abstract class WebMvcConfigurerAdapter implements WebMvcConfigurer {
|
||||
public void configureContentNegotiation(ContentNegotiationConfigurer configurer) {
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritDoc}
|
||||
* <p>This implementation is empty.
|
||||
*/
|
||||
public void configureAsyncSupport(AsyncSupportConfigurer configurer) {
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritDoc}
|
||||
* <p>This implementation is empty.
|
||||
|
||||
@@ -55,6 +55,12 @@ class WebMvcConfigurerComposite implements WebMvcConfigurer {
|
||||
}
|
||||
}
|
||||
|
||||
public void configureAsyncSupport(AsyncSupportConfigurer configurer) {
|
||||
for (WebMvcConfigurer delegate : this.delegates) {
|
||||
delegate.configureAsyncSupport(configurer);
|
||||
}
|
||||
}
|
||||
|
||||
public void configureMessageConverters(List<HttpMessageConverter<?>> converters) {
|
||||
for (WebMvcConfigurer delegate : this.delegates) {
|
||||
delegate.configureMessageConverters(converters);
|
||||
|
||||
@@ -24,6 +24,7 @@ import java.util.List;
|
||||
import java.util.Map;
|
||||
import java.util.Map.Entry;
|
||||
import java.util.Set;
|
||||
import java.util.concurrent.Callable;
|
||||
import java.util.concurrent.ConcurrentHashMap;
|
||||
|
||||
import javax.servlet.http.HttpServletRequest;
|
||||
@@ -62,6 +63,7 @@ import org.springframework.web.bind.support.WebDataBinderFactory;
|
||||
import org.springframework.web.context.request.NativeWebRequest;
|
||||
import org.springframework.web.context.request.ServletWebRequest;
|
||||
import org.springframework.web.context.request.WebRequest;
|
||||
import org.springframework.web.context.request.async.AsyncTask;
|
||||
import org.springframework.web.context.request.async.AsyncWebRequest;
|
||||
import org.springframework.web.context.request.async.AsyncWebUtils;
|
||||
import org.springframework.web.context.request.async.WebAsyncManager;
|
||||
@@ -400,26 +402,28 @@ public class RequestMappingHandlerAdapter extends AbstractHandlerMethodAdapter i
|
||||
}
|
||||
|
||||
/**
|
||||
* Set the AsyncTaskExecutor to use when a controller method returns a
|
||||
* {@code Callable}.
|
||||
* <p>The default instance type is a {@link SimpleAsyncTaskExecutor}.
|
||||
* It's recommended to change that default in production as the simple
|
||||
* executor does not re-use threads.
|
||||
* Set the default {@link AsyncTaskExecutor} to use when a controller method
|
||||
* return a {@link Callable}. Controller methods can override this default on
|
||||
* a per-request basis by returning an {@link AsyncTask}.
|
||||
* <p>By default a {@link SimpleAsyncTaskExecutor} instance is used.
|
||||
* It's recommended to change that default in production as the simple executor
|
||||
* does not re-use threads.
|
||||
*/
|
||||
public void setAsyncTaskExecutor(AsyncTaskExecutor taskExecutor) {
|
||||
public void setTaskExecutor(AsyncTaskExecutor taskExecutor) {
|
||||
this.taskExecutor = taskExecutor;
|
||||
}
|
||||
|
||||
/**
|
||||
* Set the timeout for asynchronous request processing in milliseconds.
|
||||
* When the timeout begins depends on the underlying async technology.
|
||||
* With the Servlet 3 async support the timeout begins after the main
|
||||
* processing thread has exited and has been returned to the container pool.
|
||||
* <p>If a value is not provided, the default timeout of the underlying
|
||||
* async technology is used (10 seconds on Tomcat with Servlet 3 async).
|
||||
* Specify the amount of time, in milliseconds, before concurrent handling
|
||||
* should time out. In Servlet 3, the timeout begins after the main request
|
||||
* processing thread has exited and ends when the request is dispatched again
|
||||
* for further processing of the concurrently produced result.
|
||||
* <p>If this value is not set, the default timeout of the underlying
|
||||
* implementation is used, e.g. 10 seconds on Tomcat with Servlet 3.
|
||||
* @param timeout the timeout value in milliseconds
|
||||
*/
|
||||
public void setAsyncRequestTimeout(long asyncRequestTimeout) {
|
||||
this.asyncRequestTimeout = asyncRequestTimeout;
|
||||
public void setAsyncRequestTimeout(long timeout) {
|
||||
this.asyncRequestTimeout = timeout;
|
||||
}
|
||||
|
||||
/**
|
||||
|
||||
Reference in New Issue
Block a user