From 1035e5b02967d68f4ae607e11a7bf7c67e95af72 Mon Sep 17 00:00:00 2001 From: Stephane Nicoll Date: Tue, 10 Feb 2015 16:00:11 +0100 Subject: [PATCH] Expose RepositoryRestMvcBootConfiguration If an application defines a custom RepositoryRestMvcConfiguration, all Spring Boot defaults are lots. While this sounds sensible, it can be confusing as Spring Boot exposes properties (`spring.data.rest.*`) that are no longer honored. RepositoryRestMvcBootConfiguration is now public and can be used as an extension point for those who need to customize the Spring Data REST configuration and keep boot's specific defaults. Fixes gh-2392 --- .../RepositoryRestMvcAutoConfiguration.java | 33 +--------- .../RepositoryRestMvcBootConfiguration.java | 61 +++++++++++++++++++ ...positoryRestMvcAutoConfigurationTests.java | 14 +++++ spring-boot-docs/src/main/asciidoc/howto.adoc | 13 ++++ 4 files changed, 91 insertions(+), 30 deletions(-) create mode 100644 spring-boot-autoconfigure/src/main/java/org/springframework/boot/autoconfigure/data/rest/RepositoryRestMvcBootConfiguration.java diff --git a/spring-boot-autoconfigure/src/main/java/org/springframework/boot/autoconfigure/data/rest/RepositoryRestMvcAutoConfiguration.java b/spring-boot-autoconfigure/src/main/java/org/springframework/boot/autoconfigure/data/rest/RepositoryRestMvcAutoConfiguration.java index 813f58593a..82ddd0d8c3 100644 --- a/spring-boot-autoconfigure/src/main/java/org/springframework/boot/autoconfigure/data/rest/RepositoryRestMvcAutoConfiguration.java +++ b/spring-boot-autoconfigure/src/main/java/org/springframework/boot/autoconfigure/data/rest/RepositoryRestMvcAutoConfiguration.java @@ -1,5 +1,5 @@ /* - * Copyright 2002-2014 the original author or authors. + * Copyright 2012-2015 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. @@ -16,21 +16,16 @@ package org.springframework.boot.autoconfigure.data.rest; -import org.springframework.beans.factory.annotation.Autowired; import org.springframework.boot.autoconfigure.AutoConfigureAfter; import org.springframework.boot.autoconfigure.EnableAutoConfiguration; import org.springframework.boot.autoconfigure.condition.ConditionalOnClass; import org.springframework.boot.autoconfigure.condition.ConditionalOnMissingBean; import org.springframework.boot.autoconfigure.condition.ConditionalOnWebApplication; import org.springframework.boot.autoconfigure.web.HttpMessageConvertersAutoConfiguration; -import org.springframework.boot.context.properties.ConfigurationProperties; -import org.springframework.context.annotation.Bean; import org.springframework.context.annotation.Configuration; +import org.springframework.context.annotation.Import; import org.springframework.data.rest.core.config.RepositoryRestConfiguration; import org.springframework.data.rest.webmvc.config.RepositoryRestMvcConfiguration; -import org.springframework.http.converter.json.Jackson2ObjectMapperBuilder; - -import com.fasterxml.jackson.databind.ObjectMapper; /** * {@link EnableAutoConfiguration Auto-configuration} for Spring Data Rest's MVC @@ -51,29 +46,7 @@ import com.fasterxml.jackson.databind.ObjectMapper; @ConditionalOnMissingBean(RepositoryRestMvcConfiguration.class) @ConditionalOnClass(RepositoryRestMvcConfiguration.class) @AutoConfigureAfter(HttpMessageConvertersAutoConfiguration.class) +@Import(RepositoryRestMvcBootConfiguration.class) public class RepositoryRestMvcAutoConfiguration { - @Configuration - static class RepositoryRestMvcBootConfiguration extends - RepositoryRestMvcConfiguration { - - @Autowired(required = false) - private Jackson2ObjectMapperBuilder objectMapperBuilder; - - @Bean - @ConfigurationProperties(prefix = "spring.data.rest") - @Override - public RepositoryRestConfiguration config() { - return super.config(); - } - - @Override - protected void configureJacksonObjectMapper(ObjectMapper objectMapper) { - if (this.objectMapperBuilder != null) { - this.objectMapperBuilder.configure(objectMapper); - } - } - - } - } diff --git a/spring-boot-autoconfigure/src/main/java/org/springframework/boot/autoconfigure/data/rest/RepositoryRestMvcBootConfiguration.java b/spring-boot-autoconfigure/src/main/java/org/springframework/boot/autoconfigure/data/rest/RepositoryRestMvcBootConfiguration.java new file mode 100644 index 0000000000..4e7f5ad8ba --- /dev/null +++ b/spring-boot-autoconfigure/src/main/java/org/springframework/boot/autoconfigure/data/rest/RepositoryRestMvcBootConfiguration.java @@ -0,0 +1,61 @@ +/* + * Copyright 2012-2015 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. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package org.springframework.boot.autoconfigure.data.rest; + +import com.fasterxml.jackson.databind.ObjectMapper; + +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.boot.context.properties.ConfigurationProperties; +import org.springframework.context.annotation.Bean; +import org.springframework.context.annotation.Configuration; +import org.springframework.data.rest.core.config.RepositoryRestConfiguration; +import org.springframework.data.rest.webmvc.config.RepositoryRestMvcConfiguration; +import org.springframework.http.converter.json.Jackson2ObjectMapperBuilder; + +/** + * A specialized {@link RepositoryRestMvcConfiguration} that applies configuration + * items from the {@code spring.data.rest} namespace. Also configure Jackson if it's + * available + *

+ * Favor an extension of this class instead of extending directly from + * {@link RepositoryRestMvcConfiguration}. + * + * @author Stephane Nicoll + * @since 1.2.2 + */ +@Configuration +public class RepositoryRestMvcBootConfiguration extends + RepositoryRestMvcConfiguration { + + @Autowired(required = false) + private Jackson2ObjectMapperBuilder objectMapperBuilder; + + @Bean + @ConfigurationProperties(prefix = "spring.data.rest") + @Override + public RepositoryRestConfiguration config() { + return super.config(); + } + + @Override + protected void configureJacksonObjectMapper(ObjectMapper objectMapper) { + if (this.objectMapperBuilder != null) { + this.objectMapperBuilder.configure(objectMapper); + } + } + +} diff --git a/spring-boot-autoconfigure/src/test/java/org/springframework/boot/autoconfigure/data/rest/RepositoryRestMvcAutoConfigurationTests.java b/spring-boot-autoconfigure/src/test/java/org/springframework/boot/autoconfigure/data/rest/RepositoryRestMvcAutoConfigurationTests.java index b383db98d9..52d009814c 100644 --- a/spring-boot-autoconfigure/src/test/java/org/springframework/boot/autoconfigure/data/rest/RepositoryRestMvcAutoConfigurationTests.java +++ b/spring-boot-autoconfigure/src/test/java/org/springframework/boot/autoconfigure/data/rest/RepositoryRestMvcAutoConfigurationTests.java @@ -89,7 +89,16 @@ public class RepositoryRestMvcAutoConfigurationTests { .getBean(RepositoryRestConfiguration.class); assertEquals("Custom base URI should not have been set", URI.create(""), bean.getBaseUri()); + } + @Test + public void propertiesStillAppliedWithCustomBootConfig() { + load(TestConfigurationWithRestMvcBootConfig.class, "spring.data.rest.baseUri:foo"); + assertNotNull(this.context.getBean(RepositoryRestMvcConfiguration.class)); + RepositoryRestConfiguration bean = this.context + .getBean(RepositoryRestConfiguration.class); + assertEquals("Custom base URI should have been set", URI.create("foo"), + bean.getBaseUri()); } @Test @@ -134,6 +143,11 @@ public class RepositoryRestMvcAutoConfigurationTests { } + @Import({ TestConfiguration.class, RepositoryRestMvcBootConfiguration.class }) + protected static class TestConfigurationWithRestMvcBootConfig { + + } + @Configuration @TestAutoConfigurationPackage(City.class) @EnableWebMvc diff --git a/spring-boot-docs/src/main/asciidoc/howto.adoc b/spring-boot-docs/src/main/asciidoc/howto.adoc index 4e2854f03b..565c6834c6 100644 --- a/spring-boot-docs/src/main/asciidoc/howto.adoc +++ b/spring-boot-docs/src/main/asciidoc/howto.adoc @@ -1464,6 +1464,19 @@ repository types (Elasticsearch, Solr). Just change the names of the annotations respectively. +[[howto-use-exposing-spring-data-repositories-rest-endpoint]] +=== Expose Spring Data repositories as REST endpoint + +Spring Data REST can expose the `Repository` implementations as REST endpoints for you as +long as Spring MVC has been enabled for the application. + +Spring Boot exposes as set of useful properties from the `spring.data.rest` namespace that +customize the +{spring-data-rest-javadoc}/core/config/RepositoryRestConfiguration.{dc-ext}[`RepositoryRestConfiguration`]. +If your application requires to define its own `RepositoryRestMvcConfiguration` consider +extending from `RepositoryRestMvcBootConfiguration` instead as the latter provides namely +the handling of `spring.data.rest` properties. + [[howto-database-initialization]] == Database initialization