Add config options for MVC async interceptors
The MVC namespace and the MVC Java config now allow configuring CallableProcessingInterceptor and DeferredResultProcessingInterceptor instances. Issue: SPR-9914
This commit is contained in:
@@ -175,6 +175,11 @@ public final class WebAsyncManager {
|
||||
this.callableInterceptors.put(key, interceptor);
|
||||
}
|
||||
|
||||
public void registerAllCallableInterceptors(Map<Object, CallableProcessingInterceptor> interceptors) {
|
||||
Assert.notNull(interceptors);
|
||||
this.callableInterceptors.putAll(interceptors);
|
||||
}
|
||||
|
||||
/**
|
||||
* Register a {@link DeferredResultProcessingInterceptor} that will be
|
||||
* applied when concurrent request handling with a {@link DeferredResult}
|
||||
@@ -188,6 +193,11 @@ public final class WebAsyncManager {
|
||||
this.deferredResultInterceptors.put(key, interceptor);
|
||||
}
|
||||
|
||||
public void registerAllDeferredResultInterceptors(Map<Object, DeferredResultProcessingInterceptor> interceptors) {
|
||||
Assert.notNull(interceptors);
|
||||
this.deferredResultInterceptors.putAll(interceptors);
|
||||
}
|
||||
|
||||
/**
|
||||
* Clear {@linkplain #getConcurrentResult() concurrentResult} and
|
||||
* {@linkplain #getConcurrentResultContext() concurrentResultContext}.
|
||||
|
||||
@@ -174,6 +174,8 @@ class AnnotationDrivenBeanDefinitionParser implements BeanDefinitionParser {
|
||||
ManagedList<?> returnValueHandlers = getReturnValueHandlers(element, source, parserContext);
|
||||
String asyncTimeout = getAsyncTimeout(element, source, parserContext);
|
||||
RuntimeBeanReference asyncExecutor = getAsyncExecutor(element, source, parserContext);
|
||||
ManagedList<?> callableInterceptors = getCallableInterceptors(element, source, parserContext);
|
||||
ManagedList<?> deferredResultInterceptors = getDeferredResultInterceptors(element, source, parserContext);
|
||||
|
||||
RootBeanDefinition handlerAdapterDef = new RootBeanDefinition(RequestMappingHandlerAdapter.class);
|
||||
handlerAdapterDef.setSource(source);
|
||||
@@ -197,6 +199,8 @@ class AnnotationDrivenBeanDefinitionParser implements BeanDefinitionParser {
|
||||
if (asyncExecutor != null) {
|
||||
handlerAdapterDef.getPropertyValues().add("taskExecutor", asyncExecutor);
|
||||
}
|
||||
handlerAdapterDef.getPropertyValues().add("callableInterceptors", callableInterceptors);
|
||||
handlerAdapterDef.getPropertyValues().add("deferredResultInterceptors", deferredResultInterceptors);
|
||||
String handlerAdapterName = parserContext.getReaderContext().registerWithGeneratedName(handlerAdapterDef);
|
||||
|
||||
RootBeanDefinition csInterceptorDef = new RootBeanDefinition(ConversionServiceExposingInterceptor.class);
|
||||
@@ -337,6 +341,40 @@ class AnnotationDrivenBeanDefinitionParser implements BeanDefinitionParser {
|
||||
return null;
|
||||
}
|
||||
|
||||
private ManagedList<?> getCallableInterceptors(Element element, Object source, ParserContext parserContext) {
|
||||
ManagedList<? super Object> interceptors = new ManagedList<Object>();
|
||||
Element asyncElement = DomUtils.getChildElementByTagName(element, "async-support");
|
||||
if (asyncElement != null) {
|
||||
Element interceptorsElement = DomUtils.getChildElementByTagName(asyncElement, "callable-interceptors");
|
||||
if (interceptorsElement != null) {
|
||||
interceptors.setSource(source);
|
||||
for (Element converter : DomUtils.getChildElementsByTagName(interceptorsElement, "bean")) {
|
||||
BeanDefinitionHolder beanDef = parserContext.getDelegate().parseBeanDefinitionElement(converter);
|
||||
beanDef = parserContext.getDelegate().decorateBeanDefinitionIfRequired(converter, beanDef);
|
||||
interceptors.add(beanDef);
|
||||
}
|
||||
}
|
||||
}
|
||||
return interceptors;
|
||||
}
|
||||
|
||||
private ManagedList<?> getDeferredResultInterceptors(Element element, Object source, ParserContext parserContext) {
|
||||
ManagedList<? super Object> interceptors = new ManagedList<Object>();
|
||||
Element asyncElement = DomUtils.getChildElementByTagName(element, "async-support");
|
||||
if (asyncElement != null) {
|
||||
Element interceptorsElement = DomUtils.getChildElementByTagName(asyncElement, "deferred-result-interceptors");
|
||||
if (interceptorsElement != null) {
|
||||
interceptors.setSource(source);
|
||||
for (Element converter : DomUtils.getChildElementsByTagName(interceptorsElement, "bean")) {
|
||||
BeanDefinitionHolder beanDef = parserContext.getDelegate().parseBeanDefinitionElement(converter);
|
||||
beanDef = parserContext.getDelegate().decorateBeanDefinitionIfRequired(converter, beanDef);
|
||||
interceptors.add(beanDef);
|
||||
}
|
||||
}
|
||||
}
|
||||
return interceptors;
|
||||
}
|
||||
|
||||
private ManagedList<?> getArgumentResolvers(Element element, Object source, ParserContext parserContext) {
|
||||
Element resolversElement = DomUtils.getChildElementByTagName(element, "argument-resolvers");
|
||||
if (resolversElement != null) {
|
||||
|
||||
@@ -15,11 +15,18 @@
|
||||
*/
|
||||
package org.springframework.web.servlet.config.annotation;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.Arrays;
|
||||
import java.util.List;
|
||||
import java.util.concurrent.Callable;
|
||||
|
||||
import org.springframework.core.task.AsyncTaskExecutor;
|
||||
import org.springframework.core.task.SimpleAsyncTaskExecutor;
|
||||
import org.springframework.util.Assert;
|
||||
import org.springframework.web.context.request.async.AsyncTask;
|
||||
import org.springframework.web.context.request.async.CallableProcessingInterceptor;
|
||||
import org.springframework.web.context.request.async.DeferredResult;
|
||||
import org.springframework.web.context.request.async.DeferredResultProcessingInterceptor;
|
||||
|
||||
/**
|
||||
* Helps with configuring a options for asynchronous request processing.
|
||||
@@ -33,6 +40,13 @@ public class AsyncSupportConfigurer {
|
||||
|
||||
private Long timeout;
|
||||
|
||||
private final List<CallableProcessingInterceptor> callableInterceptors =
|
||||
new ArrayList<CallableProcessingInterceptor>();
|
||||
|
||||
private final List<DeferredResultProcessingInterceptor> deferredResultInterceptors =
|
||||
new ArrayList<DeferredResultProcessingInterceptor>();
|
||||
|
||||
|
||||
/**
|
||||
* Set the default {@link AsyncTaskExecutor} to use when a controller method
|
||||
* returns a {@link Callable}. Controller methods can override this default on
|
||||
@@ -64,6 +78,31 @@ public class AsyncSupportConfigurer {
|
||||
return this;
|
||||
}
|
||||
|
||||
/**
|
||||
* Configure lifecycle intercepters with callbacks around concurrent request
|
||||
* execution that starts when a controller returns a
|
||||
* {@link java.util.concurrent.Callable}.
|
||||
*
|
||||
* @param interceptors the interceptors to register
|
||||
*/
|
||||
public AsyncSupportConfigurer registerCallableInterceptors(CallableProcessingInterceptor... interceptors) {
|
||||
Assert.notNull(interceptors, "Interceptors are required");
|
||||
this.callableInterceptors.addAll(Arrays.asList(interceptors));
|
||||
return this;
|
||||
}
|
||||
|
||||
/**
|
||||
* Configure lifecycle intercepters with callbacks around concurrent request
|
||||
* execution that starts when a controller returns a {@link DeferredResult}.
|
||||
*
|
||||
* @param interceptors the interceptors to register
|
||||
*/
|
||||
public AsyncSupportConfigurer registerDeferredResultInterceptors(DeferredResultProcessingInterceptor... interceptors) {
|
||||
Assert.notNull(interceptors, "Interceptors are required");
|
||||
this.deferredResultInterceptors.addAll(Arrays.asList(interceptors));
|
||||
return this;
|
||||
}
|
||||
|
||||
protected AsyncTaskExecutor getTaskExecutor() {
|
||||
return this.taskExecutor;
|
||||
}
|
||||
@@ -72,4 +111,12 @@ public class AsyncSupportConfigurer {
|
||||
return this.timeout;
|
||||
}
|
||||
|
||||
protected List<CallableProcessingInterceptor> getCallableInterceptors() {
|
||||
return this.callableInterceptors;
|
||||
}
|
||||
|
||||
protected List<DeferredResultProcessingInterceptor> getDeferredResultInterceptors() {
|
||||
return this.deferredResultInterceptors;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@@ -378,6 +378,8 @@ public class WebMvcConfigurationSupport implements ApplicationContextAware, Serv
|
||||
if (configurer.getTimeout() != null) {
|
||||
adapter.setAsyncRequestTimeout(configurer.getTimeout());
|
||||
}
|
||||
adapter.setCallableInterceptors(configurer.getCallableInterceptors());
|
||||
adapter.setDeferredResultInterceptors(configurer.getDeferredResultInterceptors());
|
||||
|
||||
return adapter;
|
||||
}
|
||||
|
||||
@@ -48,6 +48,7 @@ import org.springframework.http.converter.StringHttpMessageConverter;
|
||||
import org.springframework.http.converter.xml.SourceHttpMessageConverter;
|
||||
import org.springframework.http.converter.xml.XmlAwareFormHttpMessageConverter;
|
||||
import org.springframework.ui.ModelMap;
|
||||
import org.springframework.util.Assert;
|
||||
import org.springframework.util.CollectionUtils;
|
||||
import org.springframework.util.ReflectionUtils.MethodFilter;
|
||||
import org.springframework.web.accept.ContentNegotiationManager;
|
||||
@@ -64,6 +65,8 @@ 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.CallableProcessingInterceptor;
|
||||
import org.springframework.web.context.request.async.DeferredResultProcessingInterceptor;
|
||||
import org.springframework.web.context.request.async.WebAsyncManager;
|
||||
import org.springframework.web.context.request.async.WebAsyncUtils;
|
||||
import org.springframework.web.method.ControllerAdviceBean;
|
||||
@@ -135,6 +138,12 @@ public class RequestMappingHandlerAdapter extends AbstractHandlerMethodAdapter i
|
||||
|
||||
private Long asyncRequestTimeout;
|
||||
|
||||
private final Map<Object, CallableProcessingInterceptor> callableInterceptors =
|
||||
new LinkedHashMap<Object, CallableProcessingInterceptor>();
|
||||
|
||||
private final Map<Object, DeferredResultProcessingInterceptor> deferredResultInterceptors =
|
||||
new LinkedHashMap<Object, DeferredResultProcessingInterceptor>();
|
||||
|
||||
private boolean ignoreDefaultModelOnRedirect = false;
|
||||
|
||||
private int cacheSecondsForSessionAttributeHandlers = 0;
|
||||
@@ -363,6 +372,34 @@ public class RequestMappingHandlerAdapter extends AbstractHandlerMethodAdapter i
|
||||
this.asyncRequestTimeout = timeout;
|
||||
}
|
||||
|
||||
/**
|
||||
* Configure {@code CallableProcessingInterceptor}'s to register on async requests.
|
||||
* @param interceptors the interceptors to register
|
||||
*/
|
||||
public void setCallableInterceptors(List<CallableProcessingInterceptor> interceptors) {
|
||||
Assert.notNull(interceptors);
|
||||
for (int index = 0 ; index < interceptors.size(); index++) {
|
||||
CallableProcessingInterceptor interceptor = interceptors.get(index);
|
||||
this.callableInterceptors.put(getInterceptorKey(interceptor, index), interceptor);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Configure {@code DeferredResultProcessingInterceptor}'s to register on async requests.
|
||||
* @param interceptors the interceptors to register
|
||||
*/
|
||||
public void setDeferredResultInterceptors(List<DeferredResultProcessingInterceptor> interceptors) {
|
||||
Assert.notNull(interceptors);
|
||||
for (int index = 0 ; index < interceptors.size(); index++) {
|
||||
DeferredResultProcessingInterceptor interceptor = interceptors.get(index);
|
||||
this.deferredResultInterceptors.put(getInterceptorKey(interceptor, index), interceptor);
|
||||
}
|
||||
}
|
||||
|
||||
private String getInterceptorKey(Object interceptor, int index) {
|
||||
return this.hashCode() + ":" + interceptor.getClass().getName() + "#" + index;
|
||||
}
|
||||
|
||||
/**
|
||||
* By default the content of the "default" model is used both during
|
||||
* rendering and redirect scenarios. Alternatively a controller method
|
||||
@@ -703,6 +740,8 @@ public class RequestMappingHandlerAdapter extends AbstractHandlerMethodAdapter i
|
||||
final WebAsyncManager asyncManager = WebAsyncUtils.getAsyncManager(request);
|
||||
asyncManager.setTaskExecutor(this.taskExecutor);
|
||||
asyncManager.setAsyncWebRequest(asyncWebRequest);
|
||||
asyncManager.registerAllCallableInterceptors(this.callableInterceptors);
|
||||
asyncManager.registerAllDeferredResultInterceptors(this.deferredResultInterceptors);
|
||||
|
||||
if (asyncManager.hasConcurrentResult()) {
|
||||
Object result = asyncManager.getConcurrentResult();
|
||||
|
||||
@@ -97,6 +97,46 @@
|
||||
]]></xsd:documentation>
|
||||
</xsd:annotation>
|
||||
<xsd:complexType>
|
||||
<xsd:all minOccurs="0">
|
||||
<xsd:element name="callable-interceptors" minOccurs="0">
|
||||
<xsd:annotation>
|
||||
<xsd:documentation><![CDATA[
|
||||
The ordered set of interceptors that intercept the lifecycle of concurrently executed
|
||||
requests, which start after a controller returns a java.util.concurrent.Callable.
|
||||
]]></xsd:documentation>
|
||||
</xsd:annotation>
|
||||
<xsd:complexType>
|
||||
<xsd:sequence>
|
||||
<xsd:element ref="beans:bean" minOccurs="1" maxOccurs="unbounded">
|
||||
<xsd:annotation>
|
||||
<xsd:documentation><![CDATA[
|
||||
Registers a CallableProcessingInterceptor.
|
||||
]]></xsd:documentation>
|
||||
</xsd:annotation>
|
||||
</xsd:element>
|
||||
</xsd:sequence>
|
||||
</xsd:complexType>
|
||||
</xsd:element>
|
||||
<xsd:element name="deferred-result-interceptors" minOccurs="0">
|
||||
<xsd:annotation>
|
||||
<xsd:documentation><![CDATA[
|
||||
The ordered set of interceptors that intercept the lifecycle of concurrently executed
|
||||
requests, which start after a controller returns a DeferredResult.
|
||||
]]></xsd:documentation>
|
||||
</xsd:annotation>
|
||||
<xsd:complexType>
|
||||
<xsd:sequence>
|
||||
<xsd:element ref="beans:bean" minOccurs="1" maxOccurs="unbounded">
|
||||
<xsd:annotation>
|
||||
<xsd:documentation><![CDATA[
|
||||
Registers a DeferredResultProcessingInterceptor.
|
||||
]]></xsd:documentation>
|
||||
</xsd:annotation>
|
||||
</xsd:element>
|
||||
</xsd:sequence>
|
||||
</xsd:complexType>
|
||||
</xsd:element>
|
||||
</xsd:all>
|
||||
<xsd:attribute name="task-executor" type="xsd:string">
|
||||
<xsd:annotation>
|
||||
<xsd:documentation source="java:org.springframework.core.task.AsyncTaskExecutor"><![CDATA[
|
||||
|
||||
@@ -16,6 +16,13 @@
|
||||
|
||||
package org.springframework.web.servlet.config;
|
||||
|
||||
import static org.junit.Assert.assertEquals;
|
||||
import static org.junit.Assert.assertFalse;
|
||||
import static org.junit.Assert.assertNotNull;
|
||||
import static org.junit.Assert.assertNull;
|
||||
import static org.junit.Assert.assertSame;
|
||||
import static org.junit.Assert.assertTrue;
|
||||
|
||||
import java.lang.annotation.Retention;
|
||||
import java.lang.annotation.RetentionPolicy;
|
||||
import java.lang.reflect.Method;
|
||||
@@ -23,12 +30,13 @@ import java.util.Arrays;
|
||||
import java.util.Date;
|
||||
import java.util.List;
|
||||
import java.util.Locale;
|
||||
import java.util.Map;
|
||||
|
||||
import javax.servlet.RequestDispatcher;
|
||||
import javax.validation.constraints.NotNull;
|
||||
|
||||
import org.junit.Before;
|
||||
import org.junit.Test;
|
||||
|
||||
import org.springframework.beans.DirectFieldAccessor;
|
||||
import org.springframework.beans.TypeMismatchException;
|
||||
import org.springframework.beans.factory.xml.XmlBeanDefinitionReader;
|
||||
@@ -57,6 +65,10 @@ import org.springframework.web.bind.annotation.RequestMapping;
|
||||
import org.springframework.web.bind.annotation.RequestParam;
|
||||
import org.springframework.web.context.request.NativeWebRequest;
|
||||
import org.springframework.web.context.request.ServletWebRequest;
|
||||
import org.springframework.web.context.request.async.CallableProcessingInterceptor;
|
||||
import org.springframework.web.context.request.async.CallableProcessingInterceptorAdapter;
|
||||
import org.springframework.web.context.request.async.DeferredResultProcessingInterceptor;
|
||||
import org.springframework.web.context.request.async.DeferredResultProcessingInterceptorAdapter;
|
||||
import org.springframework.web.context.support.GenericWebApplicationContext;
|
||||
import org.springframework.web.method.HandlerMethod;
|
||||
import org.springframework.web.method.support.InvocableHandlerMethod;
|
||||
@@ -76,8 +88,6 @@ import org.springframework.web.servlet.resource.DefaultServletHttpRequestHandler
|
||||
import org.springframework.web.servlet.resource.ResourceHttpRequestHandler;
|
||||
import org.springframework.web.servlet.theme.ThemeChangeInterceptor;
|
||||
|
||||
import static org.junit.Assert.*;
|
||||
|
||||
/**
|
||||
* @author Keith Donald
|
||||
* @author Arjen Poutsma
|
||||
@@ -469,8 +479,18 @@ public class MvcNamespaceTests {
|
||||
|
||||
RequestMappingHandlerAdapter adapter = appContext.getBean(RequestMappingHandlerAdapter.class);
|
||||
assertNotNull(adapter);
|
||||
assertEquals(ConcurrentTaskExecutor.class, new DirectFieldAccessor(adapter).getPropertyValue("taskExecutor").getClass());
|
||||
assertEquals(2500L, new DirectFieldAccessor(adapter).getPropertyValue("asyncRequestTimeout"));
|
||||
|
||||
DirectFieldAccessor fieldAccessor = new DirectFieldAccessor(adapter);
|
||||
assertEquals(ConcurrentTaskExecutor.class, fieldAccessor.getPropertyValue("taskExecutor").getClass());
|
||||
assertEquals(2500L, fieldAccessor.getPropertyValue("asyncRequestTimeout"));
|
||||
|
||||
Map<Object, CallableProcessingInterceptor> callableInterceptors =
|
||||
(Map<Object, CallableProcessingInterceptor>) fieldAccessor.getPropertyValue("callableInterceptors");
|
||||
assertEquals(1, callableInterceptors.size());
|
||||
|
||||
Map<Object, DeferredResultProcessingInterceptor> deferredResultInterceptors =
|
||||
(Map<Object, DeferredResultProcessingInterceptor>) fieldAccessor.getPropertyValue("deferredResultInterceptors");
|
||||
assertEquals(1, deferredResultInterceptors.size());
|
||||
}
|
||||
|
||||
|
||||
@@ -539,4 +559,8 @@ public class MvcNamespaceTests {
|
||||
}
|
||||
}
|
||||
|
||||
public static class TestCallableProcessingInterceptor extends CallableProcessingInterceptorAdapter { }
|
||||
|
||||
public static class TestDeferredResultProcessingInterceptor extends DeferredResultProcessingInterceptorAdapter { }
|
||||
|
||||
}
|
||||
|
||||
@@ -21,6 +21,7 @@ import static org.junit.Assert.assertNotNull;
|
||||
|
||||
import java.util.Arrays;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
|
||||
import org.junit.Before;
|
||||
import org.junit.Test;
|
||||
@@ -46,6 +47,10 @@ import org.springframework.web.bind.annotation.RequestMapping;
|
||||
import org.springframework.web.bind.support.ConfigurableWebBindingInitializer;
|
||||
import org.springframework.web.context.request.NativeWebRequest;
|
||||
import org.springframework.web.context.request.ServletWebRequest;
|
||||
import org.springframework.web.context.request.async.CallableProcessingInterceptor;
|
||||
import org.springframework.web.context.request.async.CallableProcessingInterceptorAdapter;
|
||||
import org.springframework.web.context.request.async.DeferredResultProcessingInterceptor;
|
||||
import org.springframework.web.context.request.async.DeferredResultProcessingInterceptorAdapter;
|
||||
import org.springframework.web.context.support.StaticWebApplicationContext;
|
||||
import org.springframework.web.method.annotation.ModelAttributeMethodProcessor;
|
||||
import org.springframework.web.method.support.HandlerMethodArgumentResolver;
|
||||
@@ -117,6 +122,7 @@ public class WebMvcConfigurationSupportExtensionTests {
|
||||
assertNotNull(handler.getHandler());
|
||||
}
|
||||
|
||||
@SuppressWarnings("unchecked")
|
||||
@Test
|
||||
public void requestMappingHandlerAdapter() throws Exception {
|
||||
RequestMappingHandlerAdapter adapter = webConfig.requestMappingHandlerAdapter();
|
||||
@@ -128,22 +134,30 @@ public class WebMvcConfigurationSupportExtensionTests {
|
||||
// Message converters
|
||||
assertEquals(1, adapter.getMessageConverters().size());
|
||||
|
||||
DirectFieldAccessor fieldAccessor = new DirectFieldAccessor(adapter);
|
||||
|
||||
// Custom argument resolvers and return value handlers
|
||||
@SuppressWarnings("unchecked")
|
||||
List<HandlerMethodArgumentResolver> argResolvers= (List<HandlerMethodArgumentResolver>)
|
||||
new DirectFieldAccessor(adapter).getPropertyValue("customArgumentResolvers");
|
||||
List<HandlerMethodArgumentResolver> argResolvers =
|
||||
(List<HandlerMethodArgumentResolver>) fieldAccessor.getPropertyValue("customArgumentResolvers");
|
||||
assertEquals(1, argResolvers.size());
|
||||
|
||||
@SuppressWarnings("unchecked")
|
||||
List<HandlerMethodReturnValueHandler> handlers = (List<HandlerMethodReturnValueHandler>)
|
||||
new DirectFieldAccessor(adapter).getPropertyValue("customReturnValueHandlers");
|
||||
List<HandlerMethodReturnValueHandler> handlers =
|
||||
(List<HandlerMethodReturnValueHandler>) fieldAccessor.getPropertyValue("customReturnValueHandlers");
|
||||
assertEquals(1, handlers.size());
|
||||
|
||||
// Async support options
|
||||
assertEquals(ConcurrentTaskExecutor.class, new DirectFieldAccessor(adapter).getPropertyValue("taskExecutor").getClass());
|
||||
assertEquals(2500L, new DirectFieldAccessor(adapter).getPropertyValue("asyncRequestTimeout"));
|
||||
assertEquals(ConcurrentTaskExecutor.class, fieldAccessor.getPropertyValue("taskExecutor").getClass());
|
||||
assertEquals(2500L, fieldAccessor.getPropertyValue("asyncRequestTimeout"));
|
||||
|
||||
assertEquals(false, new DirectFieldAccessor(adapter).getPropertyValue("ignoreDefaultModelOnRedirect"));
|
||||
Map<Object, CallableProcessingInterceptor> callableInterceptors =
|
||||
(Map<Object, CallableProcessingInterceptor>) fieldAccessor.getPropertyValue("callableInterceptors");
|
||||
assertEquals(1, callableInterceptors.size());
|
||||
|
||||
Map<Object, DeferredResultProcessingInterceptor> deferredResultInterceptors =
|
||||
(Map<Object, DeferredResultProcessingInterceptor>) fieldAccessor.getPropertyValue("deferredResultInterceptors");
|
||||
assertEquals(1, deferredResultInterceptors.size());
|
||||
|
||||
assertEquals(false, fieldAccessor.getPropertyValue("ignoreDefaultModelOnRedirect"));
|
||||
}
|
||||
|
||||
@Test
|
||||
@@ -240,7 +254,9 @@ public class WebMvcConfigurationSupportExtensionTests {
|
||||
|
||||
@Override
|
||||
public void configureAsyncSupport(AsyncSupportConfigurer configurer) {
|
||||
configurer.setDefaultTimeout(2500).setTaskExecutor(new ConcurrentTaskExecutor());
|
||||
configurer.setDefaultTimeout(2500).setTaskExecutor(new ConcurrentTaskExecutor())
|
||||
.registerCallableInterceptors(new CallableProcessingInterceptorAdapter() { })
|
||||
.registerDeferredResultInterceptors(new DeferredResultProcessingInterceptorAdapter() {});
|
||||
}
|
||||
|
||||
@Override
|
||||
|
||||
@@ -5,7 +5,14 @@
|
||||
http://www.springframework.org/schema/mvc http://www.springframework.org/schema/mvc/spring-mvc-3.2.xsd">
|
||||
|
||||
<mvc:annotation-driven>
|
||||
<mvc:async-support default-timeout="2500" task-executor="executor" />
|
||||
<mvc:async-support default-timeout="2500" task-executor="executor">
|
||||
<mvc:callable-interceptors>
|
||||
<bean class="org.springframework.web.servlet.config.MvcNamespaceTests.TestCallableProcessingInterceptor" />
|
||||
</mvc:callable-interceptors>
|
||||
<mvc:deferred-result-interceptors>
|
||||
<bean class="org.springframework.web.servlet.config.MvcNamespaceTests.TestDeferredResultProcessingInterceptor" />
|
||||
</mvc:deferred-result-interceptors>
|
||||
</mvc:async-support>
|
||||
</mvc:annotation-driven>
|
||||
|
||||
<bean id="executor" class="org.springframework.scheduling.concurrent.ConcurrentTaskExecutor" />
|
||||
|
||||
1
src/dist/changelog.txt
vendored
1
src/dist/changelog.txt
vendored
@@ -32,6 +32,7 @@ Changes in version 3.2 RC1 (2012-10-29)
|
||||
* added CallableProcessingInterceptor and DeferredResultProcessingInterceptor
|
||||
* added support for wildcard media types in AbstractView and ContentNegotiationViewResolver (SPR-9807)
|
||||
* the jackson message converters now include "application/*+json" in supported media types (SPR-7905)
|
||||
* add options to configure MVC async interceptors in the MVC namespace and Java config (SPR-9914)
|
||||
|
||||
Changes in version 3.2 M2 (2012-09-11)
|
||||
--------------------------------------
|
||||
|
||||
Reference in New Issue
Block a user