Skip to content

Commit 47c8d1d

Browse files
committed
Avoid calling other bean methods in web config
This commit changes the main configuration classes for Spring MVC and Spring WebFlux to not call other bean methods when setting up the web infrastructure. This allows configuration classes extending `DelegatingWebFluxConfiguration` and `DelegatingWebMvcConfiguration` to opt-in the lite-mode, as introduced in gh-22461.
1 parent 83ce8ad commit 47c8d1d

File tree

8 files changed

+193
-101
lines changed

8 files changed

+193
-101
lines changed

spring-test/src/main/java/org/springframework/test/web/servlet/setup/StandaloneMockMvcBuilder.java

+19-6
Original file line numberDiff line numberDiff line change
@@ -62,6 +62,7 @@
6262
import org.springframework.web.servlet.i18n.AcceptHeaderLocaleResolver;
6363
import org.springframework.web.servlet.mvc.method.annotation.RequestMappingHandlerAdapter;
6464
import org.springframework.web.servlet.mvc.method.annotation.RequestMappingHandlerMapping;
65+
import org.springframework.web.servlet.resource.ResourceUrlProvider;
6566
import org.springframework.web.servlet.support.SessionFlashMapManager;
6667
import org.springframework.web.servlet.theme.FixedThemeResolver;
6768
import org.springframework.web.servlet.view.DefaultRequestToViewNameTranslator;
@@ -374,23 +375,33 @@ private void registerMvcSingletons(StubWebApplicationContext wac) {
374375
wac.addBeans(this.controllers);
375376
wac.addBeans(this.controllerAdvice);
376377

377-
RequestMappingHandlerMapping hm = config.getHandlerMapping();
378+
FormattingConversionService mvcConversionService = config.mvcConversionService();
379+
wac.addBean("mvcConversionService", mvcConversionService);
380+
ResourceUrlProvider resourceUrlProvider = config.mvcResourceUrlProvider();
381+
wac.addBean("mvcResourceUrlProvider", resourceUrlProvider);
382+
ContentNegotiationManager mvcContentNegotiationManager = config.mvcContentNegotiationManager();
383+
wac.addBean("mvcContentNegotiationManager", mvcContentNegotiationManager);
384+
Validator mvcValidator = config.mvcValidator();
385+
wac.addBean("mvcValidator", mvcValidator);
386+
387+
RequestMappingHandlerMapping hm = config.getHandlerMapping(mvcConversionService, resourceUrlProvider);
378388
if (sc != null) {
379389
hm.setServletContext(sc);
380390
}
381391
hm.setApplicationContext(wac);
382392
hm.afterPropertiesSet();
383393
wac.addBean("requestMappingHandlerMapping", hm);
384394

385-
RequestMappingHandlerAdapter ha = config.requestMappingHandlerAdapter();
395+
RequestMappingHandlerAdapter ha = config.requestMappingHandlerAdapter(mvcContentNegotiationManager,
396+
mvcConversionService, mvcValidator);
386397
if (sc != null) {
387398
ha.setServletContext(sc);
388399
}
389400
ha.setApplicationContext(wac);
390401
ha.afterPropertiesSet();
391402
wac.addBean("requestMappingHandlerAdapter", ha);
392403

393-
wac.addBean("handlerExceptionResolver", config.handlerExceptionResolver());
404+
wac.addBean("handlerExceptionResolver", config.handlerExceptionResolver(mvcContentNegotiationManager));
394405

395406
wac.addBeans(initViewResolvers(wac));
396407
wac.addBean(DispatcherServlet.LOCALE_RESOLVER_BEAN_NAME, this.localeResolver);
@@ -430,13 +441,15 @@ protected Map<String, Object> extendMvcSingletons(@Nullable ServletContext servl
430441
/** Using the MVC Java configuration as the starting point for the "standalone" setup. */
431442
private class StandaloneConfiguration extends WebMvcConfigurationSupport {
432443

433-
public RequestMappingHandlerMapping getHandlerMapping() {
444+
public RequestMappingHandlerMapping getHandlerMapping(
445+
FormattingConversionService mvcConversionService,
446+
ResourceUrlProvider mvcResourceUrlProvider) {
434447
RequestMappingHandlerMapping handlerMapping = handlerMappingFactory.get();
435448
handlerMapping.setEmbeddedValueResolver(new StaticStringValueResolver(placeholderValues));
436449
handlerMapping.setUseSuffixPatternMatch(useSuffixPatternMatch);
437450
handlerMapping.setUseTrailingSlashMatch(useTrailingSlashPatternMatch);
438451
handlerMapping.setOrder(0);
439-
handlerMapping.setInterceptors(getInterceptors());
452+
handlerMapping.setInterceptors(getInterceptors(mvcConversionService, mvcResourceUrlProvider));
440453
if (removeSemicolonContent != null) {
441454
handlerMapping.setRemoveSemicolonContent(removeSemicolonContent);
442455
}
@@ -506,7 +519,7 @@ protected void configureHandlerExceptionResolvers(List<HandlerExceptionResolver>
506519
}
507520
for (HandlerExceptionResolver resolver : handlerExceptionResolvers) {
508521
if (resolver instanceof ApplicationContextAware) {
509-
ApplicationContext applicationContext = getApplicationContext();
522+
ApplicationContext applicationContext = getApplicationContext();
510523
if (applicationContext != null) {
511524
((ApplicationContextAware) resolver).setApplicationContext(applicationContext);
512525
}

spring-webflux/src/main/java/org/springframework/web/reactive/config/DelegatingWebFluxConfiguration.java

+1-1
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
/*
2-
* Copyright 2002-2017 the original author or authors.
2+
* Copyright 2002-2019 the original author or authors.
33
*
44
* Licensed under the Apache License, Version 2.0 (the "License");
55
* you may not use this file except in compliance with the License.

spring-webflux/src/main/java/org/springframework/web/reactive/config/WebFluxConfigurationSupport.java

+44-30
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
/*
2-
* Copyright 2002-2018 the original author or authors.
2+
* Copyright 2002-2019 the original author or authors.
33
*
44
* Licensed under the Apache License, Version 2.0 (the "License");
55
* you may not use this file except in compliance with the License.
@@ -92,6 +92,10 @@ public class WebFluxConfigurationSupport implements ApplicationContextAware {
9292
@Nullable
9393
private ApplicationContext applicationContext;
9494

95+
@Nullable
96+
public final ApplicationContext getApplicationContext() {
97+
return this.applicationContext;
98+
}
9599

96100
@Override
97101
public void setApplicationContext(@Nullable ApplicationContext applicationContext) {
@@ -103,12 +107,6 @@ public void setApplicationContext(@Nullable ApplicationContext applicationContex
103107
}
104108
}
105109

106-
@Nullable
107-
public final ApplicationContext getApplicationContext() {
108-
return this.applicationContext;
109-
}
110-
111-
112110
@Bean
113111
public DispatcherHandler webHandler() {
114112
return new DispatcherHandler();
@@ -121,10 +119,11 @@ public WebExceptionHandler responseStatusExceptionHandler() {
121119
}
122120

123121
@Bean
124-
public RequestMappingHandlerMapping requestMappingHandlerMapping() {
122+
public RequestMappingHandlerMapping requestMappingHandlerMapping(
123+
RequestedContentTypeResolver webFluxContentTypeResolver) {
125124
RequestMappingHandlerMapping mapping = createRequestMappingHandlerMapping();
126125
mapping.setOrder(0);
127-
mapping.setContentTypeResolver(webFluxContentTypeResolver());
126+
mapping.setContentTypeResolver(webFluxContentTypeResolver);
128127
mapping.setCorsConfigurations(getCorsConfigurations());
129128

130129
PathMatchConfigurer configurer = getPathMatchConfigurer();
@@ -203,10 +202,10 @@ public void configurePathMatching(PathMatchConfigurer configurer) {
203202
}
204203

205204
@Bean
206-
public RouterFunctionMapping routerFunctionMapping() {
205+
public RouterFunctionMapping routerFunctionMapping(ServerCodecConfigurer serverCodecConfigurer) {
207206
RouterFunctionMapping mapping = createRouterFunctionMapping();
208207
mapping.setOrder(-1); // go before RequestMappingHandlerMapping
209-
mapping.setMessageReaders(serverCodecConfigurer().getReaders());
208+
mapping.setMessageReaders(serverCodecConfigurer.getReaders());
210209
mapping.setCorsConfigurations(getCorsConfigurations());
211210

212211
return mapping;
@@ -225,13 +224,13 @@ protected RouterFunctionMapping createRouterFunctionMapping() {
225224
* {@link #addResourceHandlers}.
226225
*/
227226
@Bean
228-
public HandlerMapping resourceHandlerMapping() {
227+
public HandlerMapping resourceHandlerMapping(ResourceUrlProvider resourceUrlProvider) {
229228
ResourceLoader resourceLoader = this.applicationContext;
230229
if (resourceLoader == null) {
231230
resourceLoader = new DefaultResourceLoader();
232231
}
233232
ResourceHandlerRegistry registry = new ResourceHandlerRegistry(resourceLoader);
234-
registry.setResourceUrlProvider(resourceUrlProvider());
233+
registry.setResourceUrlProvider(resourceUrlProvider);
235234
addResourceHandlers(registry);
236235

237236
AbstractHandlerMapping handlerMapping = registry.getHandlerMapping();
@@ -265,11 +264,15 @@ protected void addResourceHandlers(ResourceHandlerRegistry registry) {
265264
}
266265

267266
@Bean
268-
public RequestMappingHandlerAdapter requestMappingHandlerAdapter() {
267+
public RequestMappingHandlerAdapter requestMappingHandlerAdapter(
268+
ReactiveAdapterRegistry webFluxAdapterRegistry,
269+
ServerCodecConfigurer serverCodecConfigurer,
270+
FormattingConversionService webFluxConversionService,
271+
Validator webfluxValidator) {
269272
RequestMappingHandlerAdapter adapter = createRequestMappingHandlerAdapter();
270-
adapter.setMessageReaders(serverCodecConfigurer().getReaders());
271-
adapter.setWebBindingInitializer(getConfigurableWebBindingInitializer());
272-
adapter.setReactiveAdapterRegistry(webFluxAdapterRegistry());
273+
adapter.setMessageReaders(serverCodecConfigurer.getReaders());
274+
adapter.setWebBindingInitializer(getConfigurableWebBindingInitializer(webFluxConversionService, webfluxValidator));
275+
adapter.setReactiveAdapterRegistry(webFluxAdapterRegistry);
273276

274277
ArgumentResolverConfigurer configurer = new ArgumentResolverConfigurer();
275278
configureArgumentResolvers(configurer);
@@ -325,10 +328,12 @@ protected void configureHttpMessageCodecs(ServerCodecConfigurer configurer) {
325328
* Return the {@link ConfigurableWebBindingInitializer} to use for
326329
* initializing all {@link WebDataBinder} instances.
327330
*/
328-
protected ConfigurableWebBindingInitializer getConfigurableWebBindingInitializer() {
331+
protected ConfigurableWebBindingInitializer getConfigurableWebBindingInitializer(
332+
FormattingConversionService webFluxConversionService,
333+
Validator webFluxValidator) {
329334
ConfigurableWebBindingInitializer initializer = new ConfigurableWebBindingInitializer();
330-
initializer.setConversionService(webFluxConversionService());
331-
initializer.setValidator(webFluxValidator());
335+
initializer.setConversionService(webFluxConversionService);
336+
initializer.setValidator(webFluxValidator);
332337
MessageCodesResolver messageCodesResolver = getMessageCodesResolver();
333338
if (messageCodesResolver != null) {
334339
initializer.setMessageCodesResolver(messageCodesResolver);
@@ -420,33 +425,42 @@ public SimpleHandlerAdapter simpleHandlerAdapter() {
420425
}
421426

422427
@Bean
423-
public ResponseEntityResultHandler responseEntityResultHandler() {
424-
return new ResponseEntityResultHandler(serverCodecConfigurer().getWriters(),
425-
webFluxContentTypeResolver(), webFluxAdapterRegistry());
428+
public ResponseEntityResultHandler responseEntityResultHandler(
429+
ReactiveAdapterRegistry webFluxAdapterRegistry,
430+
ServerCodecConfigurer serverCodecConfigurer,
431+
RequestedContentTypeResolver webFluxContentTypeResolver) {
432+
return new ResponseEntityResultHandler(serverCodecConfigurer.getWriters(),
433+
webFluxContentTypeResolver, webFluxAdapterRegistry);
426434
}
427435

428436
@Bean
429-
public ResponseBodyResultHandler responseBodyResultHandler() {
430-
return new ResponseBodyResultHandler(serverCodecConfigurer().getWriters(),
431-
webFluxContentTypeResolver(), webFluxAdapterRegistry());
437+
public ResponseBodyResultHandler responseBodyResultHandler(
438+
ReactiveAdapterRegistry webFluxAdapterRegistry,
439+
ServerCodecConfigurer serverCodecConfigurer,
440+
RequestedContentTypeResolver webFluxContentTypeResolver) {
441+
return new ResponseBodyResultHandler(serverCodecConfigurer.getWriters(),
442+
webFluxContentTypeResolver, webFluxAdapterRegistry);
432443
}
433444

434445
@Bean
435-
public ViewResolutionResultHandler viewResolutionResultHandler() {
446+
public ViewResolutionResultHandler viewResolutionResultHandler(
447+
ReactiveAdapterRegistry webFluxAdapterRegistry,
448+
RequestedContentTypeResolver webFluxContentTypeResolver) {
436449
ViewResolverRegistry registry = getViewResolverRegistry();
437450
List<ViewResolver> resolvers = registry.getViewResolvers();
438451
ViewResolutionResultHandler handler = new ViewResolutionResultHandler(
439-
resolvers, webFluxContentTypeResolver(), webFluxAdapterRegistry());
452+
resolvers, webFluxContentTypeResolver, webFluxAdapterRegistry);
440453
handler.setDefaultViews(registry.getDefaultViews());
441454
handler.setOrder(registry.getOrder());
442455
return handler;
443456
}
444457

445458
@Bean
446-
public ServerResponseResultHandler serverResponseResultHandler() {
459+
public ServerResponseResultHandler serverResponseResultHandler(
460+
ServerCodecConfigurer serverCodecConfigurer) {
447461
List<ViewResolver> resolvers = getViewResolverRegistry().getViewResolvers();
448462
ServerResponseResultHandler handler = new ServerResponseResultHandler();
449-
handler.setMessageWriters(serverCodecConfigurer().getWriters());
463+
handler.setMessageWriters(serverCodecConfigurer.getWriters());
450464
handler.setViewResolvers(resolvers);
451465
return handler;
452466
}

spring-webflux/src/test/java/org/springframework/web/reactive/config/DelegatingWebFluxConfigurationTests.java

+18-6
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
/*
2-
* Copyright 2002-2018 the original author or authors.
2+
* Copyright 2002-2019 the original author or authors.
33
*
44
* Licensed under the Apache License, Version 2.0 (the "License");
55
* you may not use this file except in compliance with the License.
@@ -27,9 +27,12 @@
2727
import org.mockito.MockitoAnnotations;
2828

2929
import org.springframework.context.support.StaticApplicationContext;
30+
import org.springframework.core.ReactiveAdapterRegistry;
3031
import org.springframework.format.FormatterRegistry;
32+
import org.springframework.format.support.FormattingConversionService;
3133
import org.springframework.http.codec.HttpMessageWriter;
3234
import org.springframework.http.codec.ServerCodecConfigurer;
35+
import org.springframework.validation.Validator;
3336
import org.springframework.validation.beanvalidation.LocalValidatorFactoryBean;
3437
import org.springframework.web.bind.support.ConfigurableWebBindingInitializer;
3538
import org.springframework.web.reactive.accept.RequestedContentTypeResolverBuilder;
@@ -72,7 +75,7 @@ public void setup() {
7275
@Test
7376
public void requestMappingHandlerMapping() throws Exception {
7477
delegatingConfig.setConfigurers(Collections.singletonList(webFluxConfigurer));
75-
delegatingConfig.requestMappingHandlerMapping();
78+
delegatingConfig.requestMappingHandlerMapping(delegatingConfig.webFluxContentTypeResolver());
7679

7780
verify(webFluxConfigurer).configureContentTypeResolver(any(RequestedContentTypeResolverBuilder.class));
7881
verify(webFluxConfigurer).addCorsMappings(any(CorsRegistry.class));
@@ -82,9 +85,14 @@ public void requestMappingHandlerMapping() throws Exception {
8285
@Test
8386
public void requestMappingHandlerAdapter() throws Exception {
8487
delegatingConfig.setConfigurers(Collections.singletonList(webFluxConfigurer));
88+
ReactiveAdapterRegistry reactiveAdapterRegistry = delegatingConfig.webFluxAdapterRegistry();
89+
ServerCodecConfigurer serverCodecConfigurer = delegatingConfig.serverCodecConfigurer();
90+
FormattingConversionService formattingConversionService = delegatingConfig.webFluxConversionService();
91+
Validator validator = delegatingConfig.webFluxValidator();
8592

8693
ConfigurableWebBindingInitializer initializer = (ConfigurableWebBindingInitializer)
87-
this.delegatingConfig.requestMappingHandlerAdapter().getWebBindingInitializer();
94+
this.delegatingConfig.requestMappingHandlerAdapter(reactiveAdapterRegistry, serverCodecConfigurer,
95+
formattingConversionService, validator).getWebBindingInitializer();
8896

8997
verify(webFluxConfigurer).configureHttpMessageCodecs(codecsConfigurer.capture());
9098
verify(webFluxConfigurer).getValidator();
@@ -107,15 +115,18 @@ public void resourceHandlerMapping() throws Exception {
107115
return null;
108116
}).when(webFluxConfigurer).addResourceHandlers(any(ResourceHandlerRegistry.class));
109117

110-
delegatingConfig.resourceHandlerMapping();
118+
delegatingConfig.resourceHandlerMapping(delegatingConfig.resourceUrlProvider());
111119
verify(webFluxConfigurer).addResourceHandlers(any(ResourceHandlerRegistry.class));
112120
verify(webFluxConfigurer).configurePathMatching(any(PathMatchConfigurer.class));
113121
}
114122

115123
@Test
116124
public void responseBodyResultHandler() throws Exception {
117125
delegatingConfig.setConfigurers(Collections.singletonList(webFluxConfigurer));
118-
delegatingConfig.responseBodyResultHandler();
126+
delegatingConfig.responseBodyResultHandler(
127+
delegatingConfig.webFluxAdapterRegistry(),
128+
delegatingConfig.serverCodecConfigurer(),
129+
delegatingConfig.webFluxContentTypeResolver());
119130

120131
verify(webFluxConfigurer).configureHttpMessageCodecs(codecsConfigurer.capture());
121132
verify(webFluxConfigurer).configureContentTypeResolver(any(RequestedContentTypeResolverBuilder.class));
@@ -124,7 +135,8 @@ public void responseBodyResultHandler() throws Exception {
124135
@Test
125136
public void viewResolutionResultHandler() throws Exception {
126137
delegatingConfig.setConfigurers(Collections.singletonList(webFluxConfigurer));
127-
delegatingConfig.viewResolutionResultHandler();
138+
delegatingConfig.viewResolutionResultHandler(delegatingConfig.webFluxAdapterRegistry(),
139+
delegatingConfig.webFluxContentTypeResolver());
128140

129141
verify(webFluxConfigurer).configureViewResolvers(any(ViewResolverRegistry.class));
130142
}

spring-webmvc/src/main/java/org/springframework/web/servlet/config/annotation/DelegatingWebMvcConfiguration.java

+1-1
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
/*
2-
* Copyright 2002-2016 the original author or authors.
2+
* Copyright 2002-2019 the original author or authors.
33
*
44
* Licensed under the Apache License, Version 2.0 (the "License");
55
* you may not use this file except in compliance with the License.

0 commit comments

Comments
 (0)