From 81cd11b4ecb33cf16d6b7b5a1d6048011f84e9be Mon Sep 17 00:00:00 2001 From: Oliver Gierke Date: Thu, 17 Jul 2014 21:11:02 +0200 Subject: [PATCH] Improved detection of manual Spring Data repository configuration The presense of store-specific RepositoryConfigurationExtension beans is used to disable auto-configuration for JPA, Mongo, and Solr Closes #1267 --- .../jpa/JpaRepositoriesAutoConfiguration.java | 4 +- .../MongoRepositoriesAutoConfiguration.java | 6 ++- .../SolrRepositoriesAutoConfiguration.java | 7 ++- ...JpaRepositoriesAutoConfigurationTests.java | 43 ++++++++++++------ ...ngoRepositoriesAutoConfigurationTests.java | 44 ++++++++++++------- ...olrRepositoriesAutoConfigurationTests.java | 17 ++++++- 6 files changed, 85 insertions(+), 36 deletions(-) diff --git a/spring-boot-autoconfigure/src/main/java/org/springframework/boot/autoconfigure/data/jpa/JpaRepositoriesAutoConfiguration.java b/spring-boot-autoconfigure/src/main/java/org/springframework/boot/autoconfigure/data/jpa/JpaRepositoriesAutoConfiguration.java index 716eafb379..074728ea4e 100644 --- a/spring-boot-autoconfigure/src/main/java/org/springframework/boot/autoconfigure/data/jpa/JpaRepositoriesAutoConfiguration.java +++ b/spring-boot-autoconfigure/src/main/java/org/springframework/boot/autoconfigure/data/jpa/JpaRepositoriesAutoConfiguration.java @@ -30,6 +30,7 @@ import org.springframework.context.annotation.Configuration; import org.springframework.context.annotation.Import; import org.springframework.data.jpa.repository.JpaRepository; import org.springframework.data.jpa.repository.config.EnableJpaRepositories; +import org.springframework.data.jpa.repository.config.JpaRepositoryConfigExtension; import org.springframework.data.repository.core.support.RepositoryFactoryBeanSupport; import org.springframework.data.web.PageableHandlerMethodArgumentResolver; import org.springframework.data.web.config.EnableSpringDataWebSupport; @@ -56,7 +57,8 @@ import org.springframework.data.web.config.EnableSpringDataWebSupport; @Configuration @ConditionalOnBean(DataSource.class) @ConditionalOnClass(JpaRepository.class) -@ConditionalOnMissingBean(RepositoryFactoryBeanSupport.class) +@ConditionalOnMissingBean({ RepositoryFactoryBeanSupport.class, + JpaRepositoryConfigExtension.class }) @ConditionalOnProperty(value = "spring.data.jpa.repositories.enabled", match = "true", defaultMatch = true) @Import(JpaRepositoriesAutoConfigureRegistrar.class) @AutoConfigureAfter(HibernateJpaAutoConfiguration.class) diff --git a/spring-boot-autoconfigure/src/main/java/org/springframework/boot/autoconfigure/data/mongo/MongoRepositoriesAutoConfiguration.java b/spring-boot-autoconfigure/src/main/java/org/springframework/boot/autoconfigure/data/mongo/MongoRepositoriesAutoConfiguration.java index 138fc64da9..c222236f19 100644 --- a/spring-boot-autoconfigure/src/main/java/org/springframework/boot/autoconfigure/data/mongo/MongoRepositoriesAutoConfiguration.java +++ b/spring-boot-autoconfigure/src/main/java/org/springframework/boot/autoconfigure/data/mongo/MongoRepositoriesAutoConfiguration.java @@ -26,6 +26,7 @@ import org.springframework.context.annotation.Configuration; import org.springframework.context.annotation.Import; import org.springframework.data.mongodb.repository.MongoRepository; import org.springframework.data.mongodb.repository.config.EnableMongoRepositories; +import org.springframework.data.mongodb.repository.config.MongoRepositoryConfigurationExtension; import org.springframework.data.repository.core.support.RepositoryFactoryBeanSupport; import com.mongodb.Mongo; @@ -53,8 +54,9 @@ import com.mongodb.Mongo; */ @Configuration @ConditionalOnClass({ Mongo.class, MongoRepository.class }) -@ConditionalOnMissingBean(RepositoryFactoryBeanSupport.class) -@ConditionalOnProperty(value = "spring.data.mongo.repositories.enabled", match="true", defaultMatch = true) +@ConditionalOnMissingBean({ RepositoryFactoryBeanSupport.class, + MongoRepositoryConfigurationExtension.class }) +@ConditionalOnProperty(value = "spring.data.mongo.repositories.enabled", match = "true", defaultMatch = true) @Import(MongoRepositoriesAutoConfigureRegistrar.class) @AutoConfigureAfter(MongoAutoConfiguration.class) public class MongoRepositoriesAutoConfiguration { diff --git a/spring-boot-autoconfigure/src/main/java/org/springframework/boot/autoconfigure/data/solr/SolrRepositoriesAutoConfiguration.java b/spring-boot-autoconfigure/src/main/java/org/springframework/boot/autoconfigure/data/solr/SolrRepositoriesAutoConfiguration.java index 438bdfb63b..4aebec341d 100644 --- a/spring-boot-autoconfigure/src/main/java/org/springframework/boot/autoconfigure/data/solr/SolrRepositoriesAutoConfiguration.java +++ b/spring-boot-autoconfigure/src/main/java/org/springframework/boot/autoconfigure/data/solr/SolrRepositoriesAutoConfiguration.java @@ -24,6 +24,7 @@ import org.springframework.context.annotation.Configuration; import org.springframework.context.annotation.Import; import org.springframework.data.repository.core.support.RepositoryFactoryBeanSupport; import org.springframework.data.solr.repository.SolrRepository; +import org.springframework.data.solr.repository.config.SolrRepositoryConfigExtension; /** * Enables auto configuration for Spring Data Solr repositories. @@ -39,12 +40,14 @@ import org.springframework.data.solr.repository.SolrRepository; * do. * * @author Christoph Strobl + * @author Oliver Gierke * @since 1.1.0 */ @Configuration @ConditionalOnClass({ SolrServer.class, SolrRepository.class }) -@ConditionalOnMissingBean(RepositoryFactoryBeanSupport.class) -@ConditionalOnProperty(value= "spring.data.solr.repositories.enabled", match="true", defaultMatch = true) +@ConditionalOnMissingBean({ RepositoryFactoryBeanSupport.class, + SolrRepositoryConfigExtension.class }) +@ConditionalOnProperty(value = "spring.data.solr.repositories.enabled", match = "true", defaultMatch = true) @Import(SolrRepositoriesAutoConfigureRegistrar.class) public class SolrRepositoriesAutoConfiguration { diff --git a/spring-boot-autoconfigure/src/test/java/org/springframework/boot/autoconfigure/data/jpa/JpaRepositoriesAutoConfigurationTests.java b/spring-boot-autoconfigure/src/test/java/org/springframework/boot/autoconfigure/data/jpa/JpaRepositoriesAutoConfigurationTests.java index 654e00c27b..c1fbdbd92d 100644 --- a/spring-boot-autoconfigure/src/test/java/org/springframework/boot/autoconfigure/data/jpa/JpaRepositoriesAutoConfigurationTests.java +++ b/spring-boot-autoconfigure/src/test/java/org/springframework/boot/autoconfigure/data/jpa/JpaRepositoriesAutoConfigurationTests.java @@ -20,6 +20,7 @@ import javax.persistence.EntityManagerFactory; import org.junit.After; import org.junit.Test; +import org.springframework.beans.factory.NoSuchBeanDefinitionException; import org.springframework.boot.autoconfigure.PropertyPlaceholderAutoConfiguration; import org.springframework.boot.autoconfigure.TestAutoConfigurationPackage; import org.springframework.boot.autoconfigure.data.alt.mongo.CityMongoDbRepository; @@ -54,13 +55,8 @@ public class JpaRepositoriesAutoConfigurationTests { @Test public void testDefaultRepositoryConfiguration() throws Exception { - this.context = new AnnotationConfigApplicationContext(); - this.context.register(TestConfiguration.class, - EmbeddedDataSourceConfiguration.class, - HibernateJpaAutoConfiguration.class, - JpaRepositoriesAutoConfiguration.class, - PropertyPlaceholderAutoConfiguration.class); - this.context.refresh(); + prepareApplicationContext(TestConfiguration.class); + assertNotNull(this.context.getBean(CityRepository.class)); assertNotNull(this.context.getBean(PlatformTransactionManager.class)); assertNotNull(this.context.getBean(EntityManagerFactory.class)); @@ -68,19 +64,31 @@ public class JpaRepositoriesAutoConfigurationTests { @Test public void testOverrideRepositoryConfiguration() throws Exception { - this.context = new AnnotationConfigApplicationContext(); - this.context.register(CustomConfiguration.class, - EmbeddedDataSourceConfiguration.class, - HibernateJpaAutoConfiguration.class, - JpaRepositoriesAutoConfiguration.class, - PropertyPlaceholderAutoConfiguration.class); - this.context.refresh(); + prepareApplicationContext(CustomConfiguration.class); + assertNotNull(this.context .getBean(org.springframework.boot.autoconfigure.data.alt.jpa.CityJpaRepository.class)); assertNotNull(this.context.getBean(PlatformTransactionManager.class)); assertNotNull(this.context.getBean(EntityManagerFactory.class)); } + @Test(expected = NoSuchBeanDefinitionException.class) + public void autoConfigurationShouldNotKickInEvenIfManualConfigDidNotCreateAnyRepositories() { + prepareApplicationContext(SortOfInvalidCustomConfiguration.class); + + this.context.getBean(CityRepository.class); + } + + private void prepareApplicationContext(Class... configurationClasses) { + this.context = new AnnotationConfigApplicationContext(); + this.context.register(configurationClasses); + this.context.register(EmbeddedDataSourceConfiguration.class, + HibernateJpaAutoConfiguration.class, + JpaRepositoriesAutoConfiguration.class, + PropertyPlaceholderAutoConfiguration.class); + this.context.refresh(); + } + @Configuration @TestAutoConfigurationPackage(City.class) protected static class TestConfiguration { @@ -96,4 +104,11 @@ public class JpaRepositoriesAutoConfigurationTests { } + @Configuration + // To not find any repositories + @EnableJpaRepositories("foo.bar") + @TestAutoConfigurationPackage(City.class) + protected static class SortOfInvalidCustomConfiguration { + + } } diff --git a/spring-boot-autoconfigure/src/test/java/org/springframework/boot/autoconfigure/data/mongo/MongoRepositoriesAutoConfigurationTests.java b/spring-boot-autoconfigure/src/test/java/org/springframework/boot/autoconfigure/data/mongo/MongoRepositoriesAutoConfigurationTests.java index 04a79f5204..edb4abcbc6 100644 --- a/spring-boot-autoconfigure/src/test/java/org/springframework/boot/autoconfigure/data/mongo/MongoRepositoriesAutoConfigurationTests.java +++ b/spring-boot-autoconfigure/src/test/java/org/springframework/boot/autoconfigure/data/mongo/MongoRepositoriesAutoConfigurationTests.java @@ -18,6 +18,7 @@ package org.springframework.boot.autoconfigure.data.mongo; import org.junit.After; import org.junit.Test; +import org.springframework.beans.factory.NoSuchBeanDefinitionException; import org.springframework.boot.autoconfigure.PropertyPlaceholderAutoConfiguration; import org.springframework.boot.autoconfigure.TestAutoConfigurationPackage; import org.springframework.boot.autoconfigure.data.alt.mongo.CityMongoDbRepository; @@ -55,26 +56,16 @@ public class MongoRepositoriesAutoConfigurationTests { @Test public void testDefaultRepositoryConfiguration() throws Exception { - this.context = new AnnotationConfigApplicationContext(); - this.context.register(TestConfiguration.class, MongoAutoConfiguration.class, - MongoDataAutoConfiguration.class, - MongoRepositoriesAutoConfiguration.class, - PropertyPlaceholderAutoConfiguration.class); - this.context.refresh(); - assertNotNull(this.context.getBean(CityRepository.class)); + prepareApplicationContext(TestConfiguration.class); + assertNotNull(this.context.getBean(CityRepository.class)); Mongo mongo = this.context.getBean(Mongo.class); assertThat(mongo, is(instanceOf(MongoClient.class))); } @Test public void testNoRepositoryConfiguration() throws Exception { - this.context = new AnnotationConfigApplicationContext(); - this.context.register(EmptyConfiguration.class, MongoAutoConfiguration.class, - MongoDataAutoConfiguration.class, - MongoRepositoriesAutoConfiguration.class, - PropertyPlaceholderAutoConfiguration.class); - this.context.refresh(); + prepareApplicationContext(EmptyConfiguration.class); Mongo mongo = this.context.getBean(Mongo.class); assertThat(mongo, is(instanceOf(MongoClient.class))); @@ -82,13 +73,26 @@ public class MongoRepositoriesAutoConfigurationTests { @Test public void doesNotTriggerDefaultRepositoryDetectionIfCustomized() { + prepareApplicationContext(CustomizedConfiguration.class); + + assertNotNull(this.context.getBean(CityMongoDbRepository.class)); + } + + @Test(expected = NoSuchBeanDefinitionException.class) + public void autoConfigurationShouldNotKickInEvenIfManualConfigDidNotCreateAnyRepositories() { + prepareApplicationContext(SortOfInvalidCustomConfiguration.class); + + this.context.getBean(CityRepository.class); + } + + private void prepareApplicationContext(Class... configurationClasses) { this.context = new AnnotationConfigApplicationContext(); - this.context.register(CustomizedConfiguration.class, - MongoAutoConfiguration.class, MongoDataAutoConfiguration.class, + this.context.register(configurationClasses); + this.context.register(MongoAutoConfiguration.class, + MongoDataAutoConfiguration.class, MongoRepositoriesAutoConfiguration.class, PropertyPlaceholderAutoConfiguration.class); this.context.refresh(); - assertNotNull(this.context.getBean(CityMongoDbRepository.class)); } @Configuration @@ -109,4 +113,12 @@ public class MongoRepositoriesAutoConfigurationTests { protected static class CustomizedConfiguration { } + + @Configuration + // To not find any repositories + @EnableMongoRepositories("foo.bar") + @TestAutoConfigurationPackage(MongoRepositoriesAutoConfigurationTests.class) + protected static class SortOfInvalidCustomConfiguration { + + } } diff --git a/spring-boot-autoconfigure/src/test/java/org/springframework/boot/autoconfigure/data/solr/SolrRepositoriesAutoConfigurationTests.java b/spring-boot-autoconfigure/src/test/java/org/springframework/boot/autoconfigure/data/solr/SolrRepositoriesAutoConfigurationTests.java index 13144f3c45..4beccbbbf5 100644 --- a/spring-boot-autoconfigure/src/test/java/org/springframework/boot/autoconfigure/data/solr/SolrRepositoriesAutoConfigurationTests.java +++ b/spring-boot-autoconfigure/src/test/java/org/springframework/boot/autoconfigure/data/solr/SolrRepositoriesAutoConfigurationTests.java @@ -20,6 +20,7 @@ import org.apache.solr.client.solrj.SolrServer; import org.apache.solr.client.solrj.impl.HttpSolrServer; import org.junit.After; import org.junit.Test; +import org.springframework.beans.factory.NoSuchBeanDefinitionException; import org.springframework.boot.autoconfigure.PropertyPlaceholderAutoConfiguration; import org.springframework.boot.autoconfigure.TestAutoConfigurationPackage; import org.springframework.boot.autoconfigure.data.alt.solr.CitySolrRepository; @@ -36,9 +37,10 @@ import static org.hamcrest.core.IsNull.notNullValue; import static org.junit.Assert.assertThat; /** - * Tests for {@link SolrRepositoriesAutoConfiguration} + * Tests for {@link SolrRepositoriesAutoConfiguration}. * * @author Christoph Strobl + * @author Oliver Gierke */ public class SolrRepositoriesAutoConfigurationTests { @@ -71,6 +73,13 @@ public class SolrRepositoriesAutoConfigurationTests { assertThat(this.context.getBean(CitySolrRepository.class), notNullValue()); } + @Test(expected = NoSuchBeanDefinitionException.class) + public void autoConfigurationShouldNotKickInEvenIfManualConfigDidNotCreateAnyRepositories() { + + initContext(SortOfInvalidCustomConfiguration.class); + this.context.getBean(CityRepository.class); + } + private void initContext(Class configClass) { this.context = new AnnotationConfigApplicationContext(); @@ -99,4 +108,10 @@ public class SolrRepositoriesAutoConfigurationTests { } + @Configuration + @TestAutoConfigurationPackage(SolrRepositoriesAutoConfigurationTests.class) + // To not find any repositories + @EnableSolrRepositories("foo.bar") + protected static class SortOfInvalidCustomConfiguration { + } }