HandlerMappingIntrospector is a bean

This commit is contained in:
Rossen Stoyanchev 2017-09-27 21:28:49 -04:00
parent 8071f13481
commit b6ca8a9018
5 changed files with 122 additions and 48 deletions

View File

@ -28,6 +28,7 @@ import org.springframework.util.AntPathMatcher;
import org.springframework.util.PathMatcher;
import org.springframework.web.cors.CorsConfiguration;
import org.springframework.web.servlet.handler.BeanNameUrlHandlerMapping;
import org.springframework.web.servlet.handler.HandlerMappingIntrospector;
import org.springframework.web.servlet.mvc.HttpRequestHandlerAdapter;
import org.springframework.web.servlet.mvc.SimpleControllerHandlerAdapter;
import org.springframework.web.util.UrlPathHelper;
@ -56,11 +57,14 @@ abstract class MvcNamespaceUtils {
private static final String CORS_CONFIGURATION_BEAN_NAME = "mvcCorsConfigurations";
private static final String HANDLER_MAPPING_INTROSPECTOR_BEAN_NAME = "mvcHandlerMappingIntrospector";
public static void registerDefaultComponents(ParserContext parserContext, Object source) {
registerBeanNameUrlHandlerMapping(parserContext, source);
registerHttpRequestHandlerAdapter(parserContext, source);
registerSimpleControllerHandlerAdapter(parserContext, source);
registerHandlerMappingIntrospector(parserContext, source);
}
/**
@ -184,6 +188,21 @@ abstract class MvcNamespaceUtils {
return new RuntimeBeanReference(CORS_CONFIGURATION_BEAN_NAME);
}
/**
* Registers an {@link HandlerMappingIntrospector} under a well-known name
* unless already registered.
*/
private static void registerHandlerMappingIntrospector(ParserContext parserContext, Object source) {
if (!parserContext.getRegistry().containsBeanDefinition(HANDLER_MAPPING_INTROSPECTOR_BEAN_NAME)){
RootBeanDefinition beanDef = new RootBeanDefinition(HandlerMappingIntrospector.class);
beanDef.setSource(source);
beanDef.setRole(BeanDefinition.ROLE_INFRASTRUCTURE);
beanDef.setLazyInit(true);
parserContext.getRegistry().registerBeanDefinition(HANDLER_MAPPING_INTROSPECTOR_BEAN_NAME, beanDef);
parserContext.registerComponent(new BeanComponentDefinition(beanDef, HANDLER_MAPPING_INTROSPECTOR_BEAN_NAME));
}
}
/**
* Find the {@code ContentNegotiationManager} bean created by or registered
* with the {@code annotation-driven} element.

View File

@ -33,6 +33,7 @@ import org.springframework.context.ApplicationContext;
import org.springframework.context.ApplicationContextAware;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.context.annotation.Lazy;
import org.springframework.core.convert.converter.Converter;
import org.springframework.format.Formatter;
import org.springframework.format.FormatterRegistry;
@ -77,6 +78,7 @@ import org.springframework.web.servlet.handler.AbstractHandlerMapping;
import org.springframework.web.servlet.handler.BeanNameUrlHandlerMapping;
import org.springframework.web.servlet.handler.ConversionServiceExposingInterceptor;
import org.springframework.web.servlet.handler.HandlerExceptionResolverComposite;
import org.springframework.web.servlet.handler.HandlerMappingIntrospector;
import org.springframework.web.servlet.mvc.Controller;
import org.springframework.web.servlet.mvc.HttpRequestHandlerAdapter;
import org.springframework.web.servlet.mvc.SimpleControllerHandlerAdapter;
@ -954,6 +956,12 @@ public class WebMvcConfigurationSupport implements ApplicationContextAware, Serv
protected void addCorsMappings(CorsRegistry registry) {
}
@Bean @Lazy
public HandlerMappingIntrospector mvcHandlerMappingIntrospector() {
return new HandlerMappingIntrospector();
}
private static final class EmptyHandlerMapping extends AbstractHandlerMapping {

View File

@ -18,6 +18,7 @@ package org.springframework.web.servlet.handler;
import java.io.IOException;
import java.util.ArrayList;
import java.util.Collections;
import java.util.List;
import java.util.Map;
import java.util.Properties;
@ -25,11 +26,14 @@ import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletRequestWrapper;
import org.springframework.beans.factory.BeanFactoryUtils;
import org.springframework.beans.factory.InitializingBean;
import org.springframework.context.ApplicationContext;
import org.springframework.context.ApplicationContextAware;
import org.springframework.core.annotation.AnnotationAwareOrderComparator;
import org.springframework.core.io.ClassPathResource;
import org.springframework.core.io.Resource;
import org.springframework.core.io.support.PropertiesLoaderUtils;
import org.springframework.util.Assert;
import org.springframework.util.ClassUtils;
import org.springframework.util.StringUtils;
import org.springframework.web.cors.CorsConfiguration;
@ -54,33 +58,64 @@ import org.springframework.web.servlet.HandlerMapping;
* @author Rossen Stoyanchev
* @since 4.3.1
*/
public class HandlerMappingIntrospector implements CorsConfigurationSource {
public class HandlerMappingIntrospector
implements CorsConfigurationSource, ApplicationContextAware, InitializingBean {
private final List<HandlerMapping> handlerMappings;
private ApplicationContext applicationContext;
private List<HandlerMapping> handlerMappings;
/**
* Constructor for use with {@link ApplicationContextAware}.
*/
public HandlerMappingIntrospector() {
}
/**
* Constructor that detects the configured {@code HandlerMapping}s in the
* given {@code ApplicationContext} or falls back on
* "DispatcherServlet.properties" like the {@code DispatcherServlet}.
*/
@Deprecated
public HandlerMappingIntrospector(ApplicationContext context) {
this.handlerMappings = initHandlerMappings(context);
}
private static List<HandlerMapping> initHandlerMappings(ApplicationContext context) {
/**
* Return the configured HandlerMapping's.
*/
public List<HandlerMapping> getHandlerMappings() {
return this.handlerMappings;
}
@Override
public void setApplicationContext(ApplicationContext applicationContext) {
this.applicationContext = applicationContext;
}
@Override
public void afterPropertiesSet() {
if (this.handlerMappings == null) {
Assert.notNull(this.applicationContext, "No ApplicationContext");
this.handlerMappings = initHandlerMappings(this.applicationContext);
}
}
private static List<HandlerMapping> initHandlerMappings(ApplicationContext applicationContext) {
Map<String, HandlerMapping> beans = BeanFactoryUtils.beansOfTypeIncludingAncestors(
context, HandlerMapping.class, true, false);
applicationContext, HandlerMapping.class, true, false);
if (!beans.isEmpty()) {
List<HandlerMapping> mappings = new ArrayList<HandlerMapping>(beans.values());
AnnotationAwareOrderComparator.sort(mappings);
return mappings;
return Collections.unmodifiableList(mappings);
}
return initDefaultHandlerMappings(context);
return Collections.unmodifiableList(initFallback(applicationContext));
}
private static List<HandlerMapping> initDefaultHandlerMappings(ApplicationContext context) {
private static List<HandlerMapping> initFallback(ApplicationContext applicationContext) {
Properties props;
String path = "DispatcherServlet.properties";
try {
@ -97,7 +132,7 @@ public class HandlerMappingIntrospector implements CorsConfigurationSource {
for (String name : names) {
try {
Class<?> clazz = ClassUtils.forName(name, DispatcherServlet.class.getClassLoader());
Object mapping = context.getAutowireCapableBeanFactory().createBean(clazz);
Object mapping = applicationContext.getAutowireCapableBeanFactory().createBean(clazz);
result.add((HandlerMapping) mapping);
}
catch (ClassNotFoundException ex) {
@ -108,13 +143,6 @@ public class HandlerMappingIntrospector implements CorsConfigurationSource {
}
/**
* Return the configured HandlerMapping's.
*/
public List<HandlerMapping> getHandlerMappings() {
return this.handlerMappings;
}
/**
* Find the {@link HandlerMapping} that would handle the given request and
* return it as a {@link MatchableHandlerMapping} that can be used to test
@ -126,6 +154,7 @@ public class HandlerMappingIntrospector implements CorsConfigurationSource {
* @throws Exception if any of the HandlerMapping's raise an exception
*/
public MatchableHandlerMapping getMatchableHandlerMapping(HttpServletRequest request) throws Exception {
Assert.notNull(this.handlerMappings, "Handler mappings not initialized");
HttpServletRequest wrapper = new RequestAttributeChangeIgnoringWrapper(request);
for (HandlerMapping handlerMapping : this.handlerMappings) {
Object handler = handlerMapping.getHandler(wrapper);
@ -142,6 +171,7 @@ public class HandlerMappingIntrospector implements CorsConfigurationSource {
@Override
public CorsConfiguration getCorsConfiguration(HttpServletRequest request) {
Assert.notNull(this.handlerMappings, "Handler mappings not initialized");
HttpServletRequest wrapper = new RequestAttributeChangeIgnoringWrapper(request);
for (HandlerMapping handlerMapping : this.handlerMappings) {
HandlerExecutionChain handler = null;

View File

@ -97,6 +97,7 @@ import org.springframework.web.servlet.ViewResolver;
import org.springframework.web.servlet.handler.AbstractHandlerMapping;
import org.springframework.web.servlet.handler.BeanNameUrlHandlerMapping;
import org.springframework.web.servlet.handler.ConversionServiceExposingInterceptor;
import org.springframework.web.servlet.handler.HandlerMappingIntrospector;
import org.springframework.web.servlet.handler.MappedInterceptor;
import org.springframework.web.servlet.handler.SimpleUrlHandlerMapping;
import org.springframework.web.servlet.handler.UserRoleAuthorizationInterceptor;
@ -189,7 +190,7 @@ public class MvcNamespaceTests {
@Test
public void testDefaultConfig() throws Exception {
loadBeanDefinitions("mvc-config.xml", 14);
loadBeanDefinitions("mvc-config.xml");
RequestMappingHandlerMapping mapping = appContext.getBean(RequestMappingHandlerMapping.class);
assertNotNull(mapping);
@ -248,11 +249,18 @@ public class MvcNamespaceTests {
CompositeUriComponentsContributor.class);
assertNotNull(uriComponentsContributor);
String name = "mvcHandlerMappingIntrospector";
HandlerMappingIntrospector introspector = this.appContext.getBean(name, HandlerMappingIntrospector.class);
assertNotNull(introspector);
assertEquals(2, introspector.getHandlerMappings().size());
assertSame(mapping, introspector.getHandlerMappings().get(0));
assertEquals(BeanNameUrlHandlerMapping.class, introspector.getHandlerMappings().get(1).getClass());
}
@Test(expected = TypeMismatchException.class)
public void testCustomConversionService() throws Exception {
loadBeanDefinitions("mvc-config-custom-conversion-service.xml", 14);
loadBeanDefinitions("mvc-config-custom-conversion-service.xml");
RequestMappingHandlerMapping mapping = appContext.getBean(RequestMappingHandlerMapping.class);
assertNotNull(mapping);
@ -287,7 +295,7 @@ public class MvcNamespaceTests {
}
private void doTestCustomValidator(String xml) throws Exception {
loadBeanDefinitions(xml, 14);
loadBeanDefinitions(xml);
RequestMappingHandlerMapping mapping = appContext.getBean(RequestMappingHandlerMapping.class);
assertNotNull(mapping);
@ -309,7 +317,7 @@ public class MvcNamespaceTests {
@Test
public void testInterceptors() throws Exception {
loadBeanDefinitions("mvc-config-interceptors.xml", 21);
loadBeanDefinitions("mvc-config-interceptors.xml");
RequestMappingHandlerMapping mapping = appContext.getBean(RequestMappingHandlerMapping.class);
assertNotNull(mapping);
@ -345,7 +353,7 @@ public class MvcNamespaceTests {
@Test
public void testResources() throws Exception {
loadBeanDefinitions("mvc-config-resources.xml", 20);
loadBeanDefinitions("mvc-config-resources.xml");
HttpRequestHandlerAdapter adapter = appContext.getBean(HttpRequestHandlerAdapter.class);
assertNotNull(adapter);
@ -393,7 +401,7 @@ public class MvcNamespaceTests {
@Test
public void testResourcesWithOptionalAttributes() throws Exception {
loadBeanDefinitions("mvc-config-resources-optional-attrs.xml", 10);
loadBeanDefinitions("mvc-config-resources-optional-attrs.xml");
SimpleUrlHandlerMapping mapping = appContext.getBean(SimpleUrlHandlerMapping.class);
assertNotNull(mapping);
@ -408,7 +416,7 @@ public class MvcNamespaceTests {
@Test
public void testResourcesWithResolversTransformers() throws Exception {
loadBeanDefinitions("mvc-config-resources-chain.xml", 11);
loadBeanDefinitions("mvc-config-resources-chain.xml");
SimpleUrlHandlerMapping mapping = appContext.getBean(SimpleUrlHandlerMapping.class);
assertNotNull(mapping);
@ -447,7 +455,7 @@ public class MvcNamespaceTests {
@Test
public void testResourcesWithResolversTransformersCustom() throws Exception {
loadBeanDefinitions("mvc-config-resources-chain-no-auto.xml", 12);
loadBeanDefinitions("mvc-config-resources-chain-no-auto.xml");
SimpleUrlHandlerMapping mapping = appContext.getBean(SimpleUrlHandlerMapping.class);
assertNotNull(mapping);
@ -480,7 +488,7 @@ public class MvcNamespaceTests {
@Test
public void testDefaultServletHandler() throws Exception {
loadBeanDefinitions("mvc-config-default-servlet.xml", 6);
loadBeanDefinitions("mvc-config-default-servlet.xml");
HttpRequestHandlerAdapter adapter = appContext.getBean(HttpRequestHandlerAdapter.class);
assertNotNull(adapter);
@ -506,7 +514,7 @@ public class MvcNamespaceTests {
@Test
public void testDefaultServletHandlerWithOptionalAttributes() throws Exception {
loadBeanDefinitions("mvc-config-default-servlet-optional-attrs.xml", 6);
loadBeanDefinitions("mvc-config-default-servlet-optional-attrs.xml");
HttpRequestHandlerAdapter adapter = appContext.getBean(HttpRequestHandlerAdapter.class);
assertNotNull(adapter);
@ -532,7 +540,7 @@ public class MvcNamespaceTests {
@Test
public void testBeanDecoration() throws Exception {
loadBeanDefinitions("mvc-config-bean-decoration.xml", 16);
loadBeanDefinitions("mvc-config-bean-decoration.xml");
RequestMappingHandlerMapping mapping = appContext.getBean(RequestMappingHandlerMapping.class);
assertNotNull(mapping);
@ -553,7 +561,7 @@ public class MvcNamespaceTests {
@Test
public void testViewControllers() throws Exception {
loadBeanDefinitions("mvc-config-view-controllers.xml", 19);
loadBeanDefinitions("mvc-config-view-controllers.xml");
RequestMappingHandlerMapping mapping = appContext.getBean(RequestMappingHandlerMapping.class);
assertNotNull(mapping);
@ -634,7 +642,7 @@ public class MvcNamespaceTests {
/** WebSphere gives trailing servlet path slashes by default!! */
@Test
public void testViewControllersOnWebSphere() throws Exception {
loadBeanDefinitions("mvc-config-view-controllers.xml", 19);
loadBeanDefinitions("mvc-config-view-controllers.xml");
SimpleUrlHandlerMapping mapping2 = appContext.getBean(SimpleUrlHandlerMapping.class);
SimpleControllerHandlerAdapter adapter = appContext.getBean(SimpleControllerHandlerAdapter.class);
@ -678,7 +686,7 @@ public class MvcNamespaceTests {
@Test
public void testViewControllersDefaultConfig() {
loadBeanDefinitions("mvc-config-view-controllers-minimal.xml", 7);
loadBeanDefinitions("mvc-config-view-controllers-minimal.xml");
SimpleUrlHandlerMapping hm = this.appContext.getBean(SimpleUrlHandlerMapping.class);
assertNotNull(hm);
@ -701,7 +709,7 @@ public class MvcNamespaceTests {
@Test
public void testContentNegotiationManager() throws Exception {
loadBeanDefinitions("mvc-config-content-negotiation-manager.xml", 15);
loadBeanDefinitions("mvc-config-content-negotiation-manager.xml");
RequestMappingHandlerMapping mapping = appContext.getBean(RequestMappingHandlerMapping.class);
ContentNegotiationManager manager = mapping.getContentNegotiationManager();
@ -723,7 +731,7 @@ public class MvcNamespaceTests {
@Test
public void testAsyncSupportOptions() throws Exception {
loadBeanDefinitions("mvc-config-async-support.xml", 15);
loadBeanDefinitions("mvc-config-async-support.xml");
RequestMappingHandlerAdapter adapter = appContext.getBean(RequestMappingHandlerAdapter.class);
assertNotNull(adapter);
@ -743,7 +751,7 @@ public class MvcNamespaceTests {
@Test
public void testViewResolution() throws Exception {
loadBeanDefinitions("mvc-config-view-resolution.xml", 7);
loadBeanDefinitions("mvc-config-view-resolution.xml");
ViewResolverComposite compositeResolver = this.appContext.getBean(ViewResolverComposite.class);
assertNotNull(compositeResolver);
@ -834,7 +842,7 @@ public class MvcNamespaceTests {
@Test
public void testViewResolutionWithContentNegotiation() throws Exception {
loadBeanDefinitions("mvc-config-view-resolution-content-negotiation.xml", 7);
loadBeanDefinitions("mvc-config-view-resolution-content-negotiation.xml");
ViewResolverComposite compositeResolver = this.appContext.getBean(ViewResolverComposite.class);
assertNotNull(compositeResolver);
@ -858,7 +866,7 @@ public class MvcNamespaceTests {
@Test
public void testViewResolutionWithOrderSet() throws Exception {
loadBeanDefinitions("mvc-config-view-resolution-custom-order.xml", 1);
loadBeanDefinitions("mvc-config-view-resolution-custom-order.xml");
ViewResolverComposite compositeResolver = this.appContext.getBean(ViewResolverComposite.class);
assertNotNull(compositeResolver);
@ -868,7 +876,7 @@ public class MvcNamespaceTests {
@Test
public void testPathMatchingHandlerMappings() throws Exception {
loadBeanDefinitions("mvc-config-path-matching-mappings.xml", 23);
loadBeanDefinitions("mvc-config-path-matching-mappings.xml");
RequestMappingHandlerMapping requestMapping = appContext.getBean(RequestMappingHandlerMapping.class);
assertNotNull(requestMapping);
@ -889,7 +897,7 @@ public class MvcNamespaceTests {
@Test
public void testCorsMinimal() throws Exception {
loadBeanDefinitions("mvc-config-cors-minimal.xml", 14);
loadBeanDefinitions("mvc-config-cors-minimal.xml");
String[] beanNames = appContext.getBeanNamesForType(AbstractHandlerMapping.class);
assertEquals(2, beanNames.length);
@ -912,7 +920,7 @@ public class MvcNamespaceTests {
@Test
public void testCors() throws Exception {
loadBeanDefinitions("mvc-config-cors.xml", 14);
loadBeanDefinitions("mvc-config-cors.xml");
String[] beanNames = appContext.getBeanNamesForType(AbstractHandlerMapping.class);
assertEquals(2, beanNames.length);
@ -941,12 +949,11 @@ public class MvcNamespaceTests {
}
private void loadBeanDefinitions(String fileName, int expectedBeanCount) {
private void loadBeanDefinitions(String fileName) {
XmlBeanDefinitionReader reader = new XmlBeanDefinitionReader(appContext);
ClassPathResource resource = new ClassPathResource(fileName, AnnotationDrivenBeanDefinitionParserTests.class);
reader.loadBeanDefinitions(resource);
String names = Arrays.toString(this.appContext.getBeanDefinitionNames());
assertEquals("Bean names: " + names, expectedBeanCount, appContext.getBeanDefinitionCount());
appContext.refresh();
}

View File

@ -31,6 +31,7 @@ import org.springframework.mock.web.test.MockHttpServletRequest;
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.CrossOrigin;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.context.WebApplicationContext;
import org.springframework.web.context.support.AnnotationConfigWebApplicationContext;
import org.springframework.web.context.support.StaticWebApplicationContext;
import org.springframework.web.cors.CorsConfiguration;
@ -38,8 +39,10 @@ import org.springframework.web.servlet.HandlerExecutionChain;
import org.springframework.web.servlet.HandlerMapping;
import org.springframework.web.servlet.mvc.method.annotation.RequestMappingHandlerMapping;
import static org.junit.Assert.*;
import static org.springframework.web.servlet.HandlerMapping.*;
import static org.junit.Assert.assertEquals;
import static org.junit.Assert.assertNotNull;
import static org.junit.Assert.assertNull;
import static org.springframework.web.servlet.HandlerMapping.BEST_MATCHING_PATTERN_ATTRIBUTE;
/**
* Unit tests for {@link HandlerMappingIntrospector}.
@ -58,7 +61,7 @@ public class HandlerMappingIntrospectorTests {
cxt.refresh();
List<?> expected = Arrays.asList(cxt.getBean("hmA"), cxt.getBean("hmB"), cxt.getBean("hmC"));
List<HandlerMapping> actual = new HandlerMappingIntrospector(cxt).getHandlerMappings();
List<HandlerMapping> actual = getIntrospector(cxt).getHandlerMappings();
assertEquals(expected, actual);
}
@ -75,7 +78,7 @@ public class HandlerMappingIntrospectorTests {
cxt.refresh();
List<?> expected = Arrays.asList(cxt.getBean("hmC"), cxt.getBean("hmB"), cxt.getBean("hmA"));
List<HandlerMapping> actual = new HandlerMappingIntrospector(cxt).getHandlerMappings();
List<HandlerMapping> actual = getIntrospector(cxt).getHandlerMappings();
assertEquals(expected, actual);
}
@ -85,7 +88,7 @@ public class HandlerMappingIntrospectorTests {
StaticWebApplicationContext cxt = new StaticWebApplicationContext();
cxt.refresh();
List<HandlerMapping> actual = new HandlerMappingIntrospector(cxt).getHandlerMappings();
List<HandlerMapping> actual = getIntrospector(cxt).getHandlerMappings();
assertEquals(2, actual.size());
assertEquals(BeanNameUrlHandlerMapping.class, actual.get(0).getClass());
assertEquals(org.springframework.web.servlet.mvc.annotation.DefaultAnnotationHandlerMapping.class,
@ -102,7 +105,7 @@ public class HandlerMappingIntrospectorTests {
cxt.refresh();
MockHttpServletRequest request = new MockHttpServletRequest("GET", "/path");
MatchableHandlerMapping hm = new HandlerMappingIntrospector(cxt).getMatchableHandlerMapping(request);
MatchableHandlerMapping hm = getIntrospector(cxt).getMatchableHandlerMapping(request);
assertEquals(cxt.getBean("hm"), hm);
assertNull("Attributes changes not ignored", request.getAttribute(BEST_MATCHING_PATTERN_ATTRIBUTE));
@ -115,7 +118,7 @@ public class HandlerMappingIntrospectorTests {
cxt.refresh();
MockHttpServletRequest request = new MockHttpServletRequest();
new HandlerMappingIntrospector(cxt).getMatchableHandlerMapping(request);
getIntrospector(cxt).getMatchableHandlerMapping(request);
}
@Test
@ -129,7 +132,7 @@ public class HandlerMappingIntrospectorTests {
MockHttpServletRequest request = new MockHttpServletRequest("OPTIONS", "/path");
request.addHeader("Origin", "http://localhost:9000");
request.addHeader(HttpHeaders.ACCESS_CONTROL_REQUEST_METHOD, "POST");
CorsConfiguration corsConfig = new HandlerMappingIntrospector(cxt).getCorsConfiguration(request);
CorsConfiguration corsConfig = getIntrospector(cxt).getCorsConfiguration(request);
assertNotNull(corsConfig);
assertEquals(Collections.singletonList("http://localhost:9000"), corsConfig.getAllowedOrigins());
@ -144,13 +147,20 @@ public class HandlerMappingIntrospectorTests {
MockHttpServletRequest request = new MockHttpServletRequest("POST", "/path");
request.addHeader("Origin", "http://localhost:9000");
CorsConfiguration corsConfig = new HandlerMappingIntrospector(cxt).getCorsConfiguration(request);
CorsConfiguration corsConfig = getIntrospector(cxt).getCorsConfiguration(request);
assertNotNull(corsConfig);
assertEquals(Collections.singletonList("http://localhost:9000"), corsConfig.getAllowedOrigins());
assertEquals(Collections.singletonList("POST"), corsConfig.getAllowedMethods());
}
private HandlerMappingIntrospector getIntrospector(WebApplicationContext cxt) {
HandlerMappingIntrospector introspector = new HandlerMappingIntrospector();
introspector.setApplicationContext(cxt);
introspector.afterPropertiesSet();
return introspector;
}
private static class TestHandlerMapping implements HandlerMapping {