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.
This commit is contained in:
Brian Clozel
2019-03-14 18:51:23 +01:00
parent 83ce8ad79a
commit 47c8d1de7b
8 changed files with 193 additions and 101 deletions

View File

@@ -1,5 +1,5 @@
/*
* Copyright 2002-2017 the original author or authors.
* Copyright 2002-2019 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.

View File

@@ -1,5 +1,5 @@
/*
* Copyright 2002-2018 the original author or authors.
* Copyright 2002-2019 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.
@@ -92,6 +92,10 @@ public class WebFluxConfigurationSupport implements ApplicationContextAware {
@Nullable
private ApplicationContext applicationContext;
@Nullable
public final ApplicationContext getApplicationContext() {
return this.applicationContext;
}
@Override
public void setApplicationContext(@Nullable ApplicationContext applicationContext) {
@@ -103,12 +107,6 @@ public class WebFluxConfigurationSupport implements ApplicationContextAware {
}
}
@Nullable
public final ApplicationContext getApplicationContext() {
return this.applicationContext;
}
@Bean
public DispatcherHandler webHandler() {
return new DispatcherHandler();
@@ -121,10 +119,11 @@ public class WebFluxConfigurationSupport implements ApplicationContextAware {
}
@Bean
public RequestMappingHandlerMapping requestMappingHandlerMapping() {
public RequestMappingHandlerMapping requestMappingHandlerMapping(
RequestedContentTypeResolver webFluxContentTypeResolver) {
RequestMappingHandlerMapping mapping = createRequestMappingHandlerMapping();
mapping.setOrder(0);
mapping.setContentTypeResolver(webFluxContentTypeResolver());
mapping.setContentTypeResolver(webFluxContentTypeResolver);
mapping.setCorsConfigurations(getCorsConfigurations());
PathMatchConfigurer configurer = getPathMatchConfigurer();
@@ -203,10 +202,10 @@ public class WebFluxConfigurationSupport implements ApplicationContextAware {
}
@Bean
public RouterFunctionMapping routerFunctionMapping() {
public RouterFunctionMapping routerFunctionMapping(ServerCodecConfigurer serverCodecConfigurer) {
RouterFunctionMapping mapping = createRouterFunctionMapping();
mapping.setOrder(-1); // go before RequestMappingHandlerMapping
mapping.setMessageReaders(serverCodecConfigurer().getReaders());
mapping.setMessageReaders(serverCodecConfigurer.getReaders());
mapping.setCorsConfigurations(getCorsConfigurations());
return mapping;
@@ -225,13 +224,13 @@ public class WebFluxConfigurationSupport implements ApplicationContextAware {
* {@link #addResourceHandlers}.
*/
@Bean
public HandlerMapping resourceHandlerMapping() {
public HandlerMapping resourceHandlerMapping(ResourceUrlProvider resourceUrlProvider) {
ResourceLoader resourceLoader = this.applicationContext;
if (resourceLoader == null) {
resourceLoader = new DefaultResourceLoader();
}
ResourceHandlerRegistry registry = new ResourceHandlerRegistry(resourceLoader);
registry.setResourceUrlProvider(resourceUrlProvider());
registry.setResourceUrlProvider(resourceUrlProvider);
addResourceHandlers(registry);
AbstractHandlerMapping handlerMapping = registry.getHandlerMapping();
@@ -265,11 +264,15 @@ public class WebFluxConfigurationSupport implements ApplicationContextAware {
}
@Bean
public RequestMappingHandlerAdapter requestMappingHandlerAdapter() {
public RequestMappingHandlerAdapter requestMappingHandlerAdapter(
ReactiveAdapterRegistry webFluxAdapterRegistry,
ServerCodecConfigurer serverCodecConfigurer,
FormattingConversionService webFluxConversionService,
Validator webfluxValidator) {
RequestMappingHandlerAdapter adapter = createRequestMappingHandlerAdapter();
adapter.setMessageReaders(serverCodecConfigurer().getReaders());
adapter.setWebBindingInitializer(getConfigurableWebBindingInitializer());
adapter.setReactiveAdapterRegistry(webFluxAdapterRegistry());
adapter.setMessageReaders(serverCodecConfigurer.getReaders());
adapter.setWebBindingInitializer(getConfigurableWebBindingInitializer(webFluxConversionService, webfluxValidator));
adapter.setReactiveAdapterRegistry(webFluxAdapterRegistry);
ArgumentResolverConfigurer configurer = new ArgumentResolverConfigurer();
configureArgumentResolvers(configurer);
@@ -325,10 +328,12 @@ public class WebFluxConfigurationSupport implements ApplicationContextAware {
* Return the {@link ConfigurableWebBindingInitializer} to use for
* initializing all {@link WebDataBinder} instances.
*/
protected ConfigurableWebBindingInitializer getConfigurableWebBindingInitializer() {
protected ConfigurableWebBindingInitializer getConfigurableWebBindingInitializer(
FormattingConversionService webFluxConversionService,
Validator webFluxValidator) {
ConfigurableWebBindingInitializer initializer = new ConfigurableWebBindingInitializer();
initializer.setConversionService(webFluxConversionService());
initializer.setValidator(webFluxValidator());
initializer.setConversionService(webFluxConversionService);
initializer.setValidator(webFluxValidator);
MessageCodesResolver messageCodesResolver = getMessageCodesResolver();
if (messageCodesResolver != null) {
initializer.setMessageCodesResolver(messageCodesResolver);
@@ -420,33 +425,42 @@ public class WebFluxConfigurationSupport implements ApplicationContextAware {
}
@Bean
public ResponseEntityResultHandler responseEntityResultHandler() {
return new ResponseEntityResultHandler(serverCodecConfigurer().getWriters(),
webFluxContentTypeResolver(), webFluxAdapterRegistry());
public ResponseEntityResultHandler responseEntityResultHandler(
ReactiveAdapterRegistry webFluxAdapterRegistry,
ServerCodecConfigurer serverCodecConfigurer,
RequestedContentTypeResolver webFluxContentTypeResolver) {
return new ResponseEntityResultHandler(serverCodecConfigurer.getWriters(),
webFluxContentTypeResolver, webFluxAdapterRegistry);
}
@Bean
public ResponseBodyResultHandler responseBodyResultHandler() {
return new ResponseBodyResultHandler(serverCodecConfigurer().getWriters(),
webFluxContentTypeResolver(), webFluxAdapterRegistry());
public ResponseBodyResultHandler responseBodyResultHandler(
ReactiveAdapterRegistry webFluxAdapterRegistry,
ServerCodecConfigurer serverCodecConfigurer,
RequestedContentTypeResolver webFluxContentTypeResolver) {
return new ResponseBodyResultHandler(serverCodecConfigurer.getWriters(),
webFluxContentTypeResolver, webFluxAdapterRegistry);
}
@Bean
public ViewResolutionResultHandler viewResolutionResultHandler() {
public ViewResolutionResultHandler viewResolutionResultHandler(
ReactiveAdapterRegistry webFluxAdapterRegistry,
RequestedContentTypeResolver webFluxContentTypeResolver) {
ViewResolverRegistry registry = getViewResolverRegistry();
List<ViewResolver> resolvers = registry.getViewResolvers();
ViewResolutionResultHandler handler = new ViewResolutionResultHandler(
resolvers, webFluxContentTypeResolver(), webFluxAdapterRegistry());
resolvers, webFluxContentTypeResolver, webFluxAdapterRegistry);
handler.setDefaultViews(registry.getDefaultViews());
handler.setOrder(registry.getOrder());
return handler;
}
@Bean
public ServerResponseResultHandler serverResponseResultHandler() {
public ServerResponseResultHandler serverResponseResultHandler(
ServerCodecConfigurer serverCodecConfigurer) {
List<ViewResolver> resolvers = getViewResolverRegistry().getViewResolvers();
ServerResponseResultHandler handler = new ServerResponseResultHandler();
handler.setMessageWriters(serverCodecConfigurer().getWriters());
handler.setMessageWriters(serverCodecConfigurer.getWriters());
handler.setViewResolvers(resolvers);
return handler;
}

View File

@@ -1,5 +1,5 @@
/*
* Copyright 2002-2018 the original author or authors.
* Copyright 2002-2019 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.
@@ -27,9 +27,12 @@ import org.mockito.Mock;
import org.mockito.MockitoAnnotations;
import org.springframework.context.support.StaticApplicationContext;
import org.springframework.core.ReactiveAdapterRegistry;
import org.springframework.format.FormatterRegistry;
import org.springframework.format.support.FormattingConversionService;
import org.springframework.http.codec.HttpMessageWriter;
import org.springframework.http.codec.ServerCodecConfigurer;
import org.springframework.validation.Validator;
import org.springframework.validation.beanvalidation.LocalValidatorFactoryBean;
import org.springframework.web.bind.support.ConfigurableWebBindingInitializer;
import org.springframework.web.reactive.accept.RequestedContentTypeResolverBuilder;
@@ -72,7 +75,7 @@ public class DelegatingWebFluxConfigurationTests {
@Test
public void requestMappingHandlerMapping() throws Exception {
delegatingConfig.setConfigurers(Collections.singletonList(webFluxConfigurer));
delegatingConfig.requestMappingHandlerMapping();
delegatingConfig.requestMappingHandlerMapping(delegatingConfig.webFluxContentTypeResolver());
verify(webFluxConfigurer).configureContentTypeResolver(any(RequestedContentTypeResolverBuilder.class));
verify(webFluxConfigurer).addCorsMappings(any(CorsRegistry.class));
@@ -82,9 +85,14 @@ public class DelegatingWebFluxConfigurationTests {
@Test
public void requestMappingHandlerAdapter() throws Exception {
delegatingConfig.setConfigurers(Collections.singletonList(webFluxConfigurer));
ReactiveAdapterRegistry reactiveAdapterRegistry = delegatingConfig.webFluxAdapterRegistry();
ServerCodecConfigurer serverCodecConfigurer = delegatingConfig.serverCodecConfigurer();
FormattingConversionService formattingConversionService = delegatingConfig.webFluxConversionService();
Validator validator = delegatingConfig.webFluxValidator();
ConfigurableWebBindingInitializer initializer = (ConfigurableWebBindingInitializer)
this.delegatingConfig.requestMappingHandlerAdapter().getWebBindingInitializer();
this.delegatingConfig.requestMappingHandlerAdapter(reactiveAdapterRegistry, serverCodecConfigurer,
formattingConversionService, validator).getWebBindingInitializer();
verify(webFluxConfigurer).configureHttpMessageCodecs(codecsConfigurer.capture());
verify(webFluxConfigurer).getValidator();
@@ -107,7 +115,7 @@ public class DelegatingWebFluxConfigurationTests {
return null;
}).when(webFluxConfigurer).addResourceHandlers(any(ResourceHandlerRegistry.class));
delegatingConfig.resourceHandlerMapping();
delegatingConfig.resourceHandlerMapping(delegatingConfig.resourceUrlProvider());
verify(webFluxConfigurer).addResourceHandlers(any(ResourceHandlerRegistry.class));
verify(webFluxConfigurer).configurePathMatching(any(PathMatchConfigurer.class));
}
@@ -115,7 +123,10 @@ public class DelegatingWebFluxConfigurationTests {
@Test
public void responseBodyResultHandler() throws Exception {
delegatingConfig.setConfigurers(Collections.singletonList(webFluxConfigurer));
delegatingConfig.responseBodyResultHandler();
delegatingConfig.responseBodyResultHandler(
delegatingConfig.webFluxAdapterRegistry(),
delegatingConfig.serverCodecConfigurer(),
delegatingConfig.webFluxContentTypeResolver());
verify(webFluxConfigurer).configureHttpMessageCodecs(codecsConfigurer.capture());
verify(webFluxConfigurer).configureContentTypeResolver(any(RequestedContentTypeResolverBuilder.class));
@@ -124,7 +135,8 @@ public class DelegatingWebFluxConfigurationTests {
@Test
public void viewResolutionResultHandler() throws Exception {
delegatingConfig.setConfigurers(Collections.singletonList(webFluxConfigurer));
delegatingConfig.viewResolutionResultHandler();
delegatingConfig.viewResolutionResultHandler(delegatingConfig.webFluxAdapterRegistry(),
delegatingConfig.webFluxContentTypeResolver());
verify(webFluxConfigurer).configureViewResolvers(any(ViewResolverRegistry.class));
}