Require bean name match for Locale(Context)Resolver to back off

Web MVC and WebFlux look up by name the Locale(Context)Resolver beans
that they use. Previously, the auto-configured resolvers for MVC and
WebFlux would back off when any bean of the required type was defined,
irrespective of its name. If the name of the user's bean didn't match
the name used by MVC and WebFlux to find the custom resolver, the
custom resolver would be ignored and MVC and WebFlux would use their
defaults. There was no indication of this happening in the condition
evaluation report as all it would show is that the auto-configured
resolver had backed off in favour of the custom resolver. It wouldn't
show anything to explain why the custom resolver had not been used.

This commit updates the auto-configured resolvers to be conditional
on a missing bean of the name required by MVC and WebFlux. If the
user then defines a custom resolver with a different name, the
condition evaluation report will show that the auto-configured
resolver remained as the bean name didn't match.

Fixes gh-24209
pull/24230/head
Andy Wilkinson 4 years ago
parent e342d7d262
commit 4a7bc3d096

@ -70,6 +70,7 @@ import org.springframework.web.reactive.result.method.annotation.ArgumentResolve
import org.springframework.web.reactive.result.method.annotation.RequestMappingHandlerAdapter;
import org.springframework.web.reactive.result.method.annotation.RequestMappingHandlerMapping;
import org.springframework.web.reactive.result.view.ViewResolver;
import org.springframework.web.server.adapter.WebHttpHandlerBuilder;
import org.springframework.web.server.i18n.AcceptHeaderLocaleContextResolver;
import org.springframework.web.server.i18n.FixedLocaleContextResolver;
import org.springframework.web.server.i18n.LocaleContextResolver;
@ -289,7 +290,7 @@ public class WebFluxAutoConfiguration {
@Bean
@Override
@ConditionalOnMissingBean
@ConditionalOnMissingBean(name = WebHttpHandlerBuilder.LOCALE_CONTEXT_RESOLVER_BEAN_NAME)
public LocaleContextResolver localeContextResolver() {
if (this.webProperties.getLocaleResolver() == WebProperties.LocaleResolver.FIXED) {
return new FixedLocaleContextResolver(this.webProperties.getLocale());

@ -441,7 +441,7 @@ public class WebMvcAutoConfiguration {
@Override
@Bean
@ConditionalOnMissingBean
@ConditionalOnMissingBean(name = DispatcherServlet.LOCALE_RESOLVER_BEAN_NAME)
@SuppressWarnings("deprecation")
public LocaleResolver localeResolver() {
if (this.webProperties.getLocaleResolver() == WebProperties.LocaleResolver.FIXED) {

@ -79,6 +79,7 @@ import org.springframework.web.reactive.result.method.annotation.RequestMappingH
import org.springframework.web.reactive.result.method.annotation.RequestMappingHandlerMapping;
import org.springframework.web.reactive.result.view.ViewResolutionResultHandler;
import org.springframework.web.reactive.result.view.ViewResolver;
import org.springframework.web.server.ServerWebExchange;
import org.springframework.web.server.i18n.AcceptHeaderLocaleContextResolver;
import org.springframework.web.server.i18n.FixedLocaleContextResolver;
import org.springframework.web.server.i18n.LocaleContextResolver;
@ -531,10 +532,25 @@ class WebFluxAutoConfigurationTests {
}
@Test
void customLocaleContextResolver() {
this.contextRunner.withUserConfiguration(LocaleContextResolverConfiguration.class)
.run((context) -> assertThat(context).hasSingleBean(LocaleContextResolver.class)
.hasBean("customLocaleContextResolver"));
void customLocaleContextResolverWithMatchingNameReplacedAutoConfiguredLocaleContextResolver() {
this.contextRunner
.withBean("localeContextResolver", CustomLocaleContextResolver.class, CustomLocaleContextResolver::new)
.run((context) -> {
assertThat(context).hasSingleBean(LocaleContextResolver.class);
assertThat(context.getBean("localeContextResolver"))
.isInstanceOf(CustomLocaleContextResolver.class);
});
}
@Test
void customLocaleContextResolverWithDifferentNameDoesNotReplaceAutoConfiguredLocaleContextResolver() {
this.contextRunner.withBean("customLocaleContextResolver", CustomLocaleContextResolver.class,
CustomLocaleContextResolver::new).run((context) -> {
assertThat(context.getBean("customLocaleContextResolver"))
.isInstanceOf(CustomLocaleContextResolver.class);
assertThat(context.getBean("localeContextResolver"))
.isInstanceOf(AcceptHeaderLocaleContextResolver.class);
});
}
private Map<PathPattern, Object> getHandlerMap(ApplicationContext context) {
@ -767,12 +783,15 @@ class WebFluxAutoConfigurationTests {
}
@Configuration(proxyBeanMethods = false)
static class LocaleContextResolverConfiguration {
static class CustomLocaleContextResolver implements LocaleContextResolver {
@Bean
LocaleContextResolver customLocaleContextResolver() {
return new AcceptHeaderLocaleContextResolver();
@Override
public LocaleContext resolveLocaleContext(ServerWebExchange exchange) {
return () -> Locale.ENGLISH;
}
@Override
public void setLocaleContext(ServerWebExchange exchange, LocaleContext localeContext) {
}
}

@ -344,6 +344,24 @@ class WebMvcAutoConfigurationTests {
});
}
@Test
void customLocaleResolverWithMatchingNameReplacesAutoConfiguredLocaleResolver() {
this.contextRunner.withBean("localeResolver", CustomLocaleResolver.class, CustomLocaleResolver::new)
.run((context) -> {
assertThat(context).hasSingleBean(LocaleResolver.class);
assertThat(context.getBean("localeResolver")).isInstanceOf(CustomLocaleResolver.class);
});
}
@Test
void customLocaleResolverWithDifferentNameDoesNotReplaceAutoConfiguredLocaleResolver() {
this.contextRunner.withBean("customLocaleResolver", CustomLocaleResolver.class, CustomLocaleResolver::new)
.run((context) -> {
assertThat(context.getBean("customLocaleResolver")).isInstanceOf(CustomLocaleResolver.class);
assertThat(context.getBean("localeResolver")).isInstanceOf(AcceptHeaderLocaleResolver.class);
});
}
@Test
void defaultDateFormat() {
this.contextRunner.run((context) -> {
@ -1376,4 +1394,17 @@ class WebMvcAutoConfigurationTests {
}
static class CustomLocaleResolver implements LocaleResolver {
@Override
public Locale resolveLocale(HttpServletRequest request) {
return Locale.ENGLISH;
}
@Override
public void setLocale(HttpServletRequest request, HttpServletResponse response, Locale locale) {
}
}
}

Loading…
Cancel
Save