From 96d479c3d95aac5eb66f9bb3656ff7e3907ed23c Mon Sep 17 00:00:00 2001 From: Phillip Webb Date: Fri, 26 Dec 2014 11:42:10 -0800 Subject: [PATCH] Make RequestMappingHandlerMapping @Primary Update WebMvcAutoConfiguration so that the RequestMappingHandlerMapping bean is @Primary. Prior to this commit a NoUniqueBeanDefinitionException would be thrown then using the MvcUriComponentsBuilder. Fixes gh-2237 --- .../EndpointWebMvcAutoConfigurationTests.java | 13 +++++++++++ .../web/WebMvcAutoConfiguration.java | 22 ++++++++++++++++++- 2 files changed, 34 insertions(+), 1 deletion(-) diff --git a/spring-boot-actuator/src/test/java/org/springframework/boot/actuate/autoconfigure/EndpointWebMvcAutoConfigurationTests.java b/spring-boot-actuator/src/test/java/org/springframework/boot/actuate/autoconfigure/EndpointWebMvcAutoConfigurationTests.java index eb0c7c3a930..51c464a994e 100644 --- a/spring-boot-actuator/src/test/java/org/springframework/boot/actuate/autoconfigure/EndpointWebMvcAutoConfigurationTests.java +++ b/spring-boot-actuator/src/test/java/org/springframework/boot/actuate/autoconfigure/EndpointWebMvcAutoConfigurationTests.java @@ -25,6 +25,7 @@ import org.junit.After; import org.junit.Before; import org.junit.Test; import org.springframework.boot.actuate.endpoint.Endpoint; +import org.springframework.boot.actuate.endpoint.mvc.EndpointHandlerMapping; import org.springframework.boot.actuate.endpoint.mvc.MvcEndpoint; import org.springframework.boot.autoconfigure.PropertyPlaceholderAutoConfiguration; import org.springframework.boot.autoconfigure.web.DispatcherServletAutoConfiguration; @@ -54,8 +55,10 @@ import org.springframework.util.SocketUtils; import org.springframework.util.StreamUtils; import org.springframework.web.bind.annotation.RequestMapping; import org.springframework.web.bind.annotation.ResponseBody; +import org.springframework.web.servlet.mvc.method.RequestMappingInfoHandlerMapping; import static org.hamcrest.Matchers.equalTo; +import static org.hamcrest.Matchers.instanceOf; import static org.hamcrest.Matchers.not; import static org.hamcrest.Matchers.notNullValue; import static org.junit.Assert.assertFalse; @@ -229,6 +232,16 @@ public class EndpointWebMvcAutoConfigurationTests { assertAllClosed(); } + @Test + public void singleRequestMappingInfoHandlerMappingBean() throws Exception { + this.applicationContext.register(RootConfig.class, BaseConfiguration.class, + ServerPortConfig.class, EndpointWebMvcAutoConfiguration.class); + this.applicationContext.refresh(); + RequestMappingInfoHandlerMapping mapping = this.applicationContext + .getBean(RequestMappingInfoHandlerMapping.class); + assertThat(mapping, not(instanceOf(EndpointHandlerMapping.class))); + } + private void assertAllClosed() throws Exception { assertContent("/controller", ports.get().server, null); assertContent("/endpoint", ports.get().server, null); diff --git a/spring-boot-autoconfigure/src/main/java/org/springframework/boot/autoconfigure/web/WebMvcAutoConfiguration.java b/spring-boot-autoconfigure/src/main/java/org/springframework/boot/autoconfigure/web/WebMvcAutoConfiguration.java index 4455a7c1df9..e8c3764d903 100644 --- a/spring-boot-autoconfigure/src/main/java/org/springframework/boot/autoconfigure/web/WebMvcAutoConfiguration.java +++ b/spring-boot-autoconfigure/src/main/java/org/springframework/boot/autoconfigure/web/WebMvcAutoConfiguration.java @@ -41,6 +41,8 @@ import org.springframework.boot.autoconfigure.condition.ConditionalOnWebApplicat import org.springframework.boot.context.properties.EnableConfigurationProperties; import org.springframework.context.annotation.Bean; import org.springframework.context.annotation.Configuration; +import org.springframework.context.annotation.Import; +import org.springframework.context.annotation.Primary; import org.springframework.core.Ordered; import org.springframework.core.annotation.Order; import org.springframework.core.convert.converter.Converter; @@ -62,6 +64,7 @@ import org.springframework.web.servlet.DispatcherServlet; import org.springframework.web.servlet.LocaleResolver; import org.springframework.web.servlet.View; import org.springframework.web.servlet.ViewResolver; +import org.springframework.web.servlet.config.annotation.DelegatingWebMvcConfiguration; import org.springframework.web.servlet.config.annotation.EnableWebMvc; import org.springframework.web.servlet.config.annotation.ResourceHandlerRegistry; import org.springframework.web.servlet.config.annotation.ViewControllerRegistry; @@ -69,6 +72,7 @@ import org.springframework.web.servlet.config.annotation.WebMvcConfigurationSupp import org.springframework.web.servlet.config.annotation.WebMvcConfigurerAdapter; import org.springframework.web.servlet.handler.SimpleUrlHandlerMapping; import org.springframework.web.servlet.i18n.FixedLocaleResolver; +import org.springframework.web.servlet.mvc.method.annotation.RequestMappingHandlerMapping; import org.springframework.web.servlet.resource.ResourceHttpRequestHandler; import org.springframework.web.servlet.view.BeanNameViewResolver; import org.springframework.web.servlet.view.ContentNegotiatingViewResolver; @@ -127,7 +131,7 @@ public class WebMvcAutoConfiguration { // Defined as a nested config to ensure WebMvcConfigurerAdapter is not read when not // on the classpath @Configuration - @EnableWebMvc + @Import(EnableWebMvcConfiguration.class) @EnableConfigurationProperties({ WebMvcProperties.class, ResourceProperties.class }) public static class WebMvcAutoConfigurationAdapter extends WebMvcConfigurerAdapter { @@ -304,4 +308,20 @@ public class WebMvcAutoConfiguration { } + /** + * Configuration equivalent to {@code @EnableWebMvc}. + */ + @Configuration + public static class EnableWebMvcConfiguration extends DelegatingWebMvcConfiguration { + + @Bean + @Primary + @Override + public RequestMappingHandlerMapping requestMappingHandlerMapping() { + // Must be @Primary for MvcUriComponentsBuilder to work + return super.requestMappingHandlerMapping(); + } + + } + }