Refactor HandlerExecutionChain towards List-centric interceptor storage

Closes gh-25500
This commit is contained in:
Juergen Hoeller
2020-08-07 00:32:52 +02:00
parent d61c0ee57d
commit b6ef3cfad5
12 changed files with 162 additions and 188 deletions

View File

@@ -1,5 +1,5 @@
/*
* Copyright 2002-2019 the original author or authors.
* Copyright 2002-2020 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.
@@ -65,9 +65,7 @@ public class HandlerExecutionChainTests {
this.chain.addInterceptor(this.interceptor1);
this.chain.addInterceptor(this.interceptor2);
assertThat(this.chain.getInterceptors().length).isEqualTo(2);
this.chain.addInterceptor(this.interceptor3);
assertThat(this.chain.getInterceptors().length).isEqualTo(3);
}

View File

@@ -238,9 +238,9 @@ public class MvcNamespaceTests {
MockHttpServletResponse response = new MockHttpServletResponse();
HandlerExecutionChain chain = mapping.getHandler(request);
assertThat(chain.getInterceptors().length).isEqualTo(1);
assertThat(chain.getInterceptors()[0] instanceof ConversionServiceExposingInterceptor).isTrue();
ConversionServiceExposingInterceptor interceptor = (ConversionServiceExposingInterceptor) chain.getInterceptors()[0];
assertThat(chain.getInterceptorList().size()).isEqualTo(1);
assertThat(chain.getInterceptorList().get(0) instanceof ConversionServiceExposingInterceptor).isTrue();
ConversionServiceExposingInterceptor interceptor = (ConversionServiceExposingInterceptor) chain.getInterceptorList().get(0);
interceptor.preHandle(request, response, handlerMethod);
assertThat(request.getAttribute(ConversionService.class.getName())).isSameAs(appContext.getBean(ConversionService.class));
@@ -278,9 +278,9 @@ public class MvcNamespaceTests {
MockHttpServletResponse response = new MockHttpServletResponse();
HandlerExecutionChain chain = mapping.getHandler(request);
assertThat(chain.getInterceptors().length).isEqualTo(1);
assertThat(chain.getInterceptors()[0] instanceof ConversionServiceExposingInterceptor).isTrue();
ConversionServiceExposingInterceptor interceptor = (ConversionServiceExposingInterceptor) chain.getInterceptors()[0];
assertThat(chain.getInterceptorList().size()).isEqualTo(1);
assertThat(chain.getInterceptorList().get(0) instanceof ConversionServiceExposingInterceptor).isTrue();
ConversionServiceExposingInterceptor interceptor = (ConversionServiceExposingInterceptor) chain.getInterceptorList().get(0);
interceptor.preHandle(request, response, handler);
assertThat(request.getAttribute(ConversionService.class.getName())).isSameAs(appContext.getBean("conversionService"));
@@ -330,23 +330,23 @@ public class MvcNamespaceTests {
request.addParameter("theme", "green");
HandlerExecutionChain chain = mapping.getHandler(request);
assertThat(chain.getInterceptors().length).isEqualTo(4);
assertThat(chain.getInterceptors()[0] instanceof ConversionServiceExposingInterceptor).isTrue();
assertThat(chain.getInterceptors()[1] instanceof LocaleChangeInterceptor).isTrue();
assertThat(chain.getInterceptors()[2] instanceof ThemeChangeInterceptor).isTrue();
assertThat(chain.getInterceptors()[3] instanceof UserRoleAuthorizationInterceptor).isTrue();
assertThat(chain.getInterceptorList().size()).isEqualTo(4);
assertThat(chain.getInterceptorList().get(0) instanceof ConversionServiceExposingInterceptor).isTrue();
assertThat(chain.getInterceptorList().get(1) instanceof LocaleChangeInterceptor).isTrue();
assertThat(chain.getInterceptorList().get(2) instanceof ThemeChangeInterceptor).isTrue();
assertThat(chain.getInterceptorList().get(3) instanceof UserRoleAuthorizationInterceptor).isTrue();
request.setRequestURI("/admin/users");
chain = mapping.getHandler(request);
assertThat(chain.getInterceptors().length).isEqualTo(2);
assertThat(chain.getInterceptorList().size()).isEqualTo(2);
request.setRequestURI("/logged/accounts/12345");
chain = mapping.getHandler(request);
assertThat(chain.getInterceptors().length).isEqualTo(3);
assertThat(chain.getInterceptorList().size()).isEqualTo(3);
request.setRequestURI("/foo/logged");
chain = mapping.getHandler(request);
assertThat(chain.getInterceptors().length).isEqualTo(3);
assertThat(chain.getInterceptorList().size()).isEqualTo(3);
}
@Test
@@ -391,7 +391,7 @@ public class MvcNamespaceTests {
assertThat(chain.getHandler() instanceof ResourceHttpRequestHandler).isTrue();
MockHttpServletResponse response = new MockHttpServletResponse();
for (HandlerInterceptor interceptor : chain.getInterceptors()) {
for (HandlerInterceptor interceptor : chain.getInterceptorList()) {
interceptor.preHandle(request, response, chain.getHandler());
}
ModelAndView mv = adapter.handle(request, response, chain.getHandler());
@@ -555,13 +555,13 @@ public class MvcNamespaceTests {
MockHttpServletRequest request = new MockHttpServletRequest("GET", "/");
HandlerExecutionChain chain = mapping.getHandler(request);
assertThat(chain.getInterceptors().length).isEqualTo(3);
assertThat(chain.getInterceptors()[0] instanceof ConversionServiceExposingInterceptor).isTrue();
assertThat(chain.getInterceptors()[1] instanceof LocaleChangeInterceptor).isTrue();
assertThat(chain.getInterceptors()[2] instanceof ThemeChangeInterceptor).isTrue();
LocaleChangeInterceptor interceptor = (LocaleChangeInterceptor) chain.getInterceptors()[1];
assertThat(chain.getInterceptorList().size()).isEqualTo(3);
assertThat(chain.getInterceptorList().get(0) instanceof ConversionServiceExposingInterceptor).isTrue();
assertThat(chain.getInterceptorList().get(1) instanceof LocaleChangeInterceptor).isTrue();
assertThat(chain.getInterceptorList().get(2) instanceof ThemeChangeInterceptor).isTrue();
LocaleChangeInterceptor interceptor = (LocaleChangeInterceptor) chain.getInterceptorList().get(1);
assertThat(interceptor.getParamName()).isEqualTo("lang");
ThemeChangeInterceptor interceptor2 = (ThemeChangeInterceptor) chain.getInterceptors()[2];
ThemeChangeInterceptor interceptor2 = (ThemeChangeInterceptor) chain.getInterceptorList().get(2);
assertThat(interceptor2.getParamName()).isEqualTo("style");
}
@@ -581,10 +581,10 @@ public class MvcNamespaceTests {
request.setMethod("GET");
HandlerExecutionChain chain = mapping.getHandler(request);
assertThat(chain.getInterceptors().length).isEqualTo(3);
assertThat(chain.getInterceptors()[0] instanceof ConversionServiceExposingInterceptor).isTrue();
assertThat(chain.getInterceptors()[1] instanceof LocaleChangeInterceptor).isTrue();
assertThat(chain.getInterceptors()[2] instanceof ThemeChangeInterceptor).isTrue();
assertThat(chain.getInterceptorList().size()).isEqualTo(3);
assertThat(chain.getInterceptorList().get(0) instanceof ConversionServiceExposingInterceptor).isTrue();
assertThat(chain.getInterceptorList().get(1) instanceof LocaleChangeInterceptor).isTrue();
assertThat(chain.getInterceptorList().get(2) instanceof ThemeChangeInterceptor).isTrue();
SimpleUrlHandlerMapping mapping2 = appContext.getBean(SimpleUrlHandlerMapping.class);
assertThat(mapping2).isNotNull();
@@ -594,10 +594,10 @@ public class MvcNamespaceTests {
request = new MockHttpServletRequest("GET", "/foo");
chain = mapping2.getHandler(request);
assertThat(chain.getInterceptors().length).isEqualTo(4);
assertThat(chain.getInterceptors()[1] instanceof ConversionServiceExposingInterceptor).isTrue();
assertThat(chain.getInterceptors()[2] instanceof LocaleChangeInterceptor).isTrue();
assertThat(chain.getInterceptors()[3] instanceof ThemeChangeInterceptor).isTrue();
assertThat(chain.getInterceptorList().size()).isEqualTo(4);
assertThat(chain.getInterceptorList().get(1) instanceof ConversionServiceExposingInterceptor).isTrue();
assertThat(chain.getInterceptorList().get(2) instanceof LocaleChangeInterceptor).isTrue();
assertThat(chain.getInterceptorList().get(3) instanceof ThemeChangeInterceptor).isTrue();
ModelAndView mv = adapter.handle(request, new MockHttpServletResponse(), chain.getHandler());
assertThat((Object) mv.getViewName()).isNull();
@@ -605,10 +605,10 @@ public class MvcNamespaceTests {
request.setContextPath("/myapp");
request.setServletPath("/app");
chain = mapping2.getHandler(request);
assertThat(chain.getInterceptors().length).isEqualTo(4);
assertThat(chain.getInterceptors()[1] instanceof ConversionServiceExposingInterceptor).isTrue();
assertThat(chain.getInterceptors()[2] instanceof LocaleChangeInterceptor).isTrue();
assertThat(chain.getInterceptors()[3] instanceof ThemeChangeInterceptor).isTrue();
assertThat(chain.getInterceptorList().size()).isEqualTo(4);
assertThat(chain.getInterceptorList().get(1) instanceof ConversionServiceExposingInterceptor).isTrue();
assertThat(chain.getInterceptorList().get(2) instanceof LocaleChangeInterceptor).isTrue();
assertThat(chain.getInterceptorList().get(3) instanceof ThemeChangeInterceptor).isTrue();
mv = adapter.handle(request, new MockHttpServletResponse(), chain.getHandler());
assertThat(mv.getViewName()).isEqualTo("baz");
@@ -616,10 +616,10 @@ public class MvcNamespaceTests {
request.setContextPath("/myapp");
request.setServletPath("/app");
chain = mapping2.getHandler(request);
assertThat(chain.getInterceptors().length).isEqualTo(4);
assertThat(chain.getInterceptors()[1] instanceof ConversionServiceExposingInterceptor).isTrue();
assertThat(chain.getInterceptors()[2] instanceof LocaleChangeInterceptor).isTrue();
assertThat(chain.getInterceptors()[3] instanceof ThemeChangeInterceptor).isTrue();
assertThat(chain.getInterceptorList().size()).isEqualTo(4);
assertThat(chain.getInterceptorList().get(1) instanceof ConversionServiceExposingInterceptor).isTrue();
assertThat(chain.getInterceptorList().get(2) instanceof LocaleChangeInterceptor).isTrue();
assertThat(chain.getInterceptorList().get(3) instanceof ThemeChangeInterceptor).isTrue();
mv = adapter.handle(request, new MockHttpServletResponse(), chain.getHandler());
assertThat(mv.getViewName()).isEqualTo("root");
@@ -660,10 +660,10 @@ public class MvcNamespaceTests {
request.setServletPath("/app/");
request.setAttribute("com.ibm.websphere.servlet.uri_non_decoded", "/myapp/app/bar");
HandlerExecutionChain chain = mapping2.getHandler(request);
assertThat(chain.getInterceptors().length).isEqualTo(4);
assertThat(chain.getInterceptors()[1] instanceof ConversionServiceExposingInterceptor).isTrue();
assertThat(chain.getInterceptors()[2] instanceof LocaleChangeInterceptor).isTrue();
assertThat(chain.getInterceptors()[3] instanceof ThemeChangeInterceptor).isTrue();
assertThat(chain.getInterceptorList().size()).isEqualTo(4);
assertThat(chain.getInterceptorList().get(1) instanceof ConversionServiceExposingInterceptor).isTrue();
assertThat(chain.getInterceptorList().get(2) instanceof LocaleChangeInterceptor).isTrue();
assertThat(chain.getInterceptorList().get(3) instanceof ThemeChangeInterceptor).isTrue();
ModelAndView mv2 = adapter.handle(request, new MockHttpServletResponse(), chain.getHandler());
assertThat(mv2.getViewName()).isEqualTo("baz");
@@ -671,10 +671,10 @@ public class MvcNamespaceTests {
request.setContextPath("/myapp");
request.setServletPath("/app/");
chain = mapping2.getHandler(request);
assertThat(chain.getInterceptors().length).isEqualTo(4);
assertThat(chain.getInterceptors()[1] instanceof ConversionServiceExposingInterceptor).isTrue();
assertThat(chain.getInterceptors()[2] instanceof LocaleChangeInterceptor).isTrue();
assertThat(chain.getInterceptors()[3] instanceof ThemeChangeInterceptor).isTrue();
assertThat(chain.getInterceptorList().size()).isEqualTo(4);
assertThat(chain.getInterceptorList().get(1) instanceof ConversionServiceExposingInterceptor).isTrue();
assertThat(chain.getInterceptorList().get(2) instanceof LocaleChangeInterceptor).isTrue();
assertThat(chain.getInterceptorList().get(3) instanceof ThemeChangeInterceptor).isTrue();
ModelAndView mv3 = adapter.handle(request, new MockHttpServletResponse(), chain.getHandler());
assertThat(mv3.getViewName()).isEqualTo("root");
@@ -682,10 +682,10 @@ public class MvcNamespaceTests {
request.setContextPath("/myapp");
request.setServletPath("/");
chain = mapping2.getHandler(request);
assertThat(chain.getInterceptors().length).isEqualTo(4);
assertThat(chain.getInterceptors()[1] instanceof ConversionServiceExposingInterceptor).isTrue();
assertThat(chain.getInterceptors()[2] instanceof LocaleChangeInterceptor).isTrue();
assertThat(chain.getInterceptors()[3] instanceof ThemeChangeInterceptor).isTrue();
assertThat(chain.getInterceptorList().size()).isEqualTo(4);
assertThat(chain.getInterceptorList().get(1) instanceof ConversionServiceExposingInterceptor).isTrue();
assertThat(chain.getInterceptorList().get(2) instanceof LocaleChangeInterceptor).isTrue();
assertThat(chain.getInterceptorList().get(3) instanceof ThemeChangeInterceptor).isTrue();
mv3 = adapter.handle(request, new MockHttpServletResponse(), chain.getHandler());
assertThat(mv3.getViewName()).isEqualTo("root");
}

View File

@@ -64,6 +64,7 @@ import org.springframework.web.method.support.HandlerMethodArgumentResolver;
import org.springframework.web.method.support.HandlerMethodReturnValueHandler;
import org.springframework.web.servlet.HandlerExceptionResolver;
import org.springframework.web.servlet.HandlerExecutionChain;
import org.springframework.web.servlet.HandlerInterceptor;
import org.springframework.web.servlet.View;
import org.springframework.web.servlet.ViewResolver;
import org.springframework.web.servlet.handler.AbstractHandlerMapping;
@@ -136,12 +137,13 @@ public class WebMvcConfigurationSupportExtensionTests {
assertThat(rmHandlerMapping.getPathMatcher().getClass()).isEqualTo(TestPathMatcher.class);
HandlerExecutionChain chain = rmHandlerMapping.getHandler(new MockHttpServletRequest("GET", "/"));
assertThat(chain).isNotNull();
assertThat(chain.getInterceptors()).isNotNull();
assertThat(chain.getInterceptors().length).isEqualTo(4);
assertThat(chain.getInterceptors()[0].getClass().getSimpleName()).isEqualTo("CorsInterceptor");
assertThat(chain.getInterceptors()[1].getClass()).isEqualTo(LocaleChangeInterceptor.class);
assertThat(chain.getInterceptors()[2].getClass()).isEqualTo(ConversionServiceExposingInterceptor.class);
assertThat(chain.getInterceptors()[3].getClass()).isEqualTo(ResourceUrlProviderExposingInterceptor.class);
HandlerInterceptor[] interceptors = chain.getInterceptors();
assertThat(interceptors).isNotNull();
assertThat(interceptors.length).isEqualTo(4);
assertThat(interceptors[0].getClass().getSimpleName()).isEqualTo("CorsInterceptor");
assertThat(interceptors[1].getClass()).isEqualTo(LocaleChangeInterceptor.class);
assertThat(interceptors[2].getClass()).isEqualTo(ConversionServiceExposingInterceptor.class);
assertThat(interceptors[3].getClass()).isEqualTo(ResourceUrlProviderExposingInterceptor.class);
Map<RequestMappingInfo, HandlerMethod> map = rmHandlerMapping.getHandlerMethods();
assertThat(map.size()).isEqualTo(2);
@@ -180,12 +182,13 @@ public class WebMvcConfigurationSupportExtensionTests {
chain = handlerMapping.getHandler(new MockHttpServletRequest("GET", "/resources/foo.gif"));
assertThat(chain).isNotNull();
assertThat(chain.getHandler()).isNotNull();
assertThat(chain.getInterceptors().length).as(Arrays.toString(chain.getInterceptors())).isEqualTo(5);
assertThat(chain.getInterceptors()[0].getClass().getSimpleName()).isEqualTo("CorsInterceptor");
// PathExposingHandlerInterceptor at chain.getInterceptors()[1]
assertThat(chain.getInterceptors()[2].getClass()).isEqualTo(LocaleChangeInterceptor.class);
assertThat(chain.getInterceptors()[3].getClass()).isEqualTo(ConversionServiceExposingInterceptor.class);
assertThat(chain.getInterceptors()[4].getClass()).isEqualTo(ResourceUrlProviderExposingInterceptor.class);
interceptors = chain.getInterceptors();
assertThat(interceptors.length).as(Arrays.toString(interceptors)).isEqualTo(5);
assertThat(interceptors[0].getClass().getSimpleName()).isEqualTo("CorsInterceptor");
// PathExposingHandlerInterceptor at interceptors[1]
assertThat(interceptors[2].getClass()).isEqualTo(LocaleChangeInterceptor.class);
assertThat(interceptors[3].getClass()).isEqualTo(ConversionServiceExposingInterceptor.class);
assertThat(interceptors[4].getClass()).isEqualTo(ResourceUrlProviderExposingInterceptor.class);
handlerMapping = (AbstractHandlerMapping) this.config.defaultServletHandlerMapping();
handlerMapping.setApplicationContext(this.context);

View File

@@ -66,6 +66,7 @@ import org.springframework.web.method.support.ModelAndViewContainer;
import org.springframework.web.servlet.FlashMapManager;
import org.springframework.web.servlet.HandlerExceptionResolver;
import org.springframework.web.servlet.HandlerExecutionChain;
import org.springframework.web.servlet.HandlerInterceptor;
import org.springframework.web.servlet.HandlerMapping;
import org.springframework.web.servlet.LocaleResolver;
import org.springframework.web.servlet.RequestToViewNameTranslator;
@@ -123,8 +124,9 @@ public class WebMvcConfigurationSupportTests {
HandlerExecutionChain chain = handlerMapping.getHandler(new MockHttpServletRequest("GET", "/"));
assertThat(chain).isNotNull();
assertThat(chain.getInterceptors()).isNotNull();
assertThat(chain.getInterceptors()[0].getClass()).isEqualTo(ConversionServiceExposingInterceptor.class);
HandlerInterceptor[] interceptors = chain.getInterceptors();
assertThat(interceptors).isNotNull();
assertThat(interceptors[0].getClass()).isEqualTo(ConversionServiceExposingInterceptor.class);
chain = handlerMapping.getHandler(new MockHttpServletRequest("GET", "/scoped"));
assertThat(chain).as("HandlerExecutionChain for '/scoped' mapping should not be null.").isNotNull();
@@ -162,10 +164,11 @@ public class WebMvcConfigurationSupportTests {
HandlerExecutionChain chain = handlerMapping.getHandler(request);
assertThat(chain).isNotNull();
assertThat(chain.getInterceptors()).isNotNull();
assertThat(chain.getInterceptors().length).isEqualTo(3);
assertThat(chain.getInterceptors()[1].getClass()).isEqualTo(ConversionServiceExposingInterceptor.class);
assertThat(chain.getInterceptors()[2].getClass()).isEqualTo(ResourceUrlProviderExposingInterceptor.class);
HandlerInterceptor[] interceptors = chain.getInterceptors();
assertThat(interceptors).isNotNull();
assertThat(interceptors.length).isEqualTo(3);
assertThat(interceptors[1].getClass()).isEqualTo(ConversionServiceExposingInterceptor.class);
assertThat(interceptors[2].getClass()).isEqualTo(ResourceUrlProviderExposingInterceptor.class);
}
@Test

View File

@@ -35,6 +35,7 @@ import static org.mockito.Mockito.mock;
/**
* Unit tests for {@link org.springframework.web.servlet.HandlerMapping}.
*
* @author Brian Clozel
* @author Rossen Stoyanchev
*/
@@ -65,17 +66,13 @@ class HandlerMappingTests {
mapping.setApplicationContext(new StaticWebApplicationContext());
HandlerExecutionChain chain = mapping.getHandler(requestFactory.apply("/"));
assertThat(chain).isNotNull();
assertThat(chain.getInterceptors()).contains(i1.getInterceptor(), i2, i3.getInterceptor(), i4);
assertThat(chain.getInterceptorList()).contains(i1.getInterceptor(), i2, i3.getInterceptor(), i4);
}
private static class TestHandlerMapping extends AbstractHandlerMapping {
TestHandlerMapping() {
}
@Override
protected Object getHandlerInternal(HttpServletRequest request) {
initLookupPath(request);

View File

@@ -273,14 +273,11 @@ public class PathMatchingUrlHandlerMappingTests {
ServletRequestPathUtils.parseAndCache(request);
}
HandlerExecutionChain executionChain = mapping.getHandler(request);
HandlerInterceptor[] interceptors = executionChain.getInterceptors();
if (interceptors != null) {
for (HandlerInterceptor interceptor : interceptors) {
interceptor.preHandle(request, null, executionChain.getHandler());
}
HandlerExecutionChain chain = mapping.getHandler(request);
for (HandlerInterceptor interceptor : chain.getInterceptorList()) {
interceptor.preHandle(request, null, chain.getHandler());
}
return executionChain;
return chain;
}
}

View File

@@ -158,11 +158,8 @@ public class SimpleUrlHandlerMappingTests {
private HandlerExecutionChain getHandler(HandlerMapping mapping, MockHttpServletRequest request) throws Exception {
HandlerExecutionChain chain = mapping.getHandler(request);
HandlerInterceptor[] interceptors = chain.getInterceptors();
if (interceptors != null) {
for (HandlerInterceptor interceptor : interceptors) {
interceptor.preHandle(request, null, chain.getHandler());
}
for (HandlerInterceptor interceptor : chain.getInterceptorList()) {
interceptor.preHandle(request, null, chain.getHandler());
}
return chain;
}

View File

@@ -239,8 +239,7 @@ class RequestMappingInfoHandlerMappingTests {
HandlerExecutionChain chain = mapping.getHandler(new MockHttpServletRequest("GET", path));
assertThat(chain).isNotNull();
assertThat(chain.getInterceptors()).isNotNull();
assertThat(chain.getInterceptors()[0]).isSameAs(interceptor);
assertThat(chain.getInterceptorList().get(0)).isSameAs(interceptor);
chain = mapping.getHandler(new MockHttpServletRequest("GET", "/invalid"));
assertThat(chain).isNull();

View File

@@ -373,13 +373,10 @@ class CrossOriginTests {
return (CorsConfiguration)accessor.getPropertyValue("config");
}
else {
HandlerInterceptor[] interceptors = chain.getInterceptors();
if (interceptors != null) {
for (HandlerInterceptor interceptor : interceptors) {
if (interceptor.getClass().getSimpleName().equals("CorsInterceptor")) {
DirectFieldAccessor accessor = new DirectFieldAccessor(interceptor);
return (CorsConfiguration) accessor.getPropertyValue("config");
}
for (HandlerInterceptor interceptor : chain.getInterceptorList()) {
if (interceptor.getClass().getSimpleName().equals("CorsInterceptor")) {
DirectFieldAccessor accessor = new DirectFieldAccessor(interceptor);
return (CorsConfiguration) accessor.getPropertyValue("config");
}
}
}