From 9bca55a8c4323029187294be3e5ae5a171ce0746 Mon Sep 17 00:00:00 2001 From: Oliver Gierke Date: Mon, 14 Nov 2016 12:08:17 +0100 Subject: [PATCH] DATACMNS-836 - Improve reactive repository configuration. MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit RepositoryConfigurationExtensionSupport now exposes a ….useRepositoryConfiguration(RepositoryMetadata) so that extensions can opt in or out of an interface taking part in configuration more easily. Turned loadRepositoryInterface(…) private again as extensions should be able to just inspect the RepositoryMetadata now. Some parameter rename in ReactiveWrapperConverters to avoid confusion. --- ...positoryConfigurationExtensionSupport.java | 35 ++++++++++++++----- .../util/ReactiveWrapperConverters.java | 12 +++---- ...onfigurationExtensionSupportUnitTests.java | 18 +++++++--- 3 files changed, 46 insertions(+), 19 deletions(-) diff --git a/src/main/java/org/springframework/data/repository/config/RepositoryConfigurationExtensionSupport.java b/src/main/java/org/springframework/data/repository/config/RepositoryConfigurationExtensionSupport.java index aab9a0717..fa94d4522 100644 --- a/src/main/java/org/springframework/data/repository/config/RepositoryConfigurationExtensionSupport.java +++ b/src/main/java/org/springframework/data/repository/config/RepositoryConfigurationExtensionSupport.java @@ -87,15 +87,25 @@ public abstract class RepositoryConfigurationExtensionSupport implements Reposit for (BeanDefinition candidate : configSource.getCandidates(loader)) { RepositoryConfiguration configuration = getRepositoryConfiguration(candidate, configSource); + Class repositoryInterface = loadRepositoryInterface(configuration, loader); + + if (repositoryInterface == null) { + result.add(configuration); + continue; + } + + RepositoryMetadata metadata = AbstractRepositoryMetadata.getMetadata(repositoryInterface); + + if (!useRepositoryConfiguration(metadata)) { + continue; + } if (!strictMatchesOnly || configSource.usesExplicitFilters()) { result.add(configuration); continue; } - Class repositoryInterface = loadRepositoryInterface(configuration, loader); - - if (repositoryInterface == null || isStrictRepositoryCandidate(repositoryInterface)) { + if (isStrictRepositoryCandidate(metadata)) { result.add(configuration); } } @@ -246,7 +256,7 @@ public abstract class RepositoryConfigurationExtensionSupport implements Reposit } /** - * Returns whether the given repository interface is a candidate for bean definition creation in the strict repository + * Returns whether the given repository metadata is a candidate for bean definition creation in the strict repository * detection mode. The default implementation inspects the domain type managed for a set of well-known annotations * (see {@link #getIdentifyingAnnotations()}). If none of them is found, the candidate is discarded. Implementations * should make sure, the only return {@literal true} if they're really sure the interface handed to the method is @@ -256,11 +266,10 @@ public abstract class RepositoryConfigurationExtensionSupport implements Reposit * @return * @since 1.9 */ - protected boolean isStrictRepositoryCandidate(Class repositoryInterface) { - - RepositoryMetadata metadata = AbstractRepositoryMetadata.getMetadata(repositoryInterface); + protected boolean isStrictRepositoryCandidate(RepositoryMetadata metadata) { Collection> types = getIdentifyingTypes(); + Class repositoryInterface = metadata.getRepositoryInterface(); for (Class type : types) { if (type.isAssignableFrom(repositoryInterface)) { @@ -286,6 +295,16 @@ public abstract class RepositoryConfigurationExtensionSupport implements Reposit return false; } + /** + * Return whether to use the configuration for the repository with the given metadata. Defaults to {@literal true}. + * + * @param metadata will never be {@literal null}. + * @return + */ + protected boolean useRepositoryConfiguration(RepositoryMetadata metadata) { + return true; + } + /** * Loads the repository interface contained in the given {@link RepositoryConfiguration} using the given * {@link ResourceLoader}. @@ -294,7 +313,7 @@ public abstract class RepositoryConfigurationExtensionSupport implements Reposit * @param loader must not be {@literal null}. * @return the repository interface or {@literal null} if it can't be loaded. */ - protected Class loadRepositoryInterface(RepositoryConfiguration configuration, ResourceLoader loader) { + private Class loadRepositoryInterface(RepositoryConfiguration configuration, ResourceLoader loader) { String repositoryInterface = configuration.getRepositoryInterface(); ClassLoader classLoader = loader.getClassLoader(); diff --git a/src/main/java/org/springframework/data/repository/util/ReactiveWrapperConverters.java b/src/main/java/org/springframework/data/repository/util/ReactiveWrapperConverters.java index c6a0a85ef..af9fe156c 100644 --- a/src/main/java/org/springframework/data/repository/util/ReactiveWrapperConverters.java +++ b/src/main/java/org/springframework/data/repository/util/ReactiveWrapperConverters.java @@ -193,21 +193,21 @@ public class ReactiveWrapperConverters { /** * Maps elements of a reactive element stream to other elements. * - * @param stream must not be {@literal null}. + * @param reactiveObject must not be {@literal null}. * @param converter must not be {@literal null}. * @return */ @SuppressWarnings("unchecked") - public static T map(Object stream, Function converter) { + public static T map(Object reactiveObject, Function converter) { - Assert.notNull(stream, "Stream must not be null!"); + Assert.notNull(reactiveObject, "Reactive source object must not be null!"); Assert.notNull(converter, "Converter must not be null!"); return REACTIVE_WRAPPERS.stream()// - .filter(it -> ClassUtils.isAssignable(it.getWrapperClass(), stream.getClass()))// + .filter(it -> ClassUtils.isAssignable(it.getWrapperClass(), reactiveObject.getClass()))// .findFirst()// - .map(it -> (T) it.map(stream, converter))// - .orElseThrow(() -> new IllegalStateException(String.format("Cannot apply converter to %s", stream))); + .map(it -> (T) it.map(reactiveObject, converter))// + .orElseThrow(() -> new IllegalStateException(String.format("Cannot apply converter to %s", reactiveObject))); } // ------------------------------------------------------------------------- diff --git a/src/test/java/org/springframework/data/repository/config/RepositoryConfigurationExtensionSupportUnitTests.java b/src/test/java/org/springframework/data/repository/config/RepositoryConfigurationExtensionSupportUnitTests.java index 5bee74d04..e3fd0501d 100644 --- a/src/test/java/org/springframework/data/repository/config/RepositoryConfigurationExtensionSupportUnitTests.java +++ b/src/test/java/org/springframework/data/repository/config/RepositoryConfigurationExtensionSupportUnitTests.java @@ -30,6 +30,8 @@ import org.springframework.core.io.DefaultResourceLoader; import org.springframework.core.type.AnnotationMetadata; import org.springframework.core.type.StandardAnnotationMetadata; import org.springframework.data.repository.Repository; +import org.springframework.data.repository.core.RepositoryMetadata; +import org.springframework.data.repository.core.support.AbstractRepositoryMetadata; import org.springframework.data.repository.core.support.RepositoryFactorySupport; /** @@ -46,7 +48,9 @@ public class RepositoryConfigurationExtensionSupportUnitTests { */ @Test public void doesNotConsiderRepositoryForPlainTypeStrictMatch() { - assertThat(extension.isStrictRepositoryCandidate(PlainTypeRepository.class), is(false)); + + RepositoryMetadata metadata = AbstractRepositoryMetadata.getMetadata(PlainTypeRepository.class); + assertThat(extension.isStrictRepositoryCandidate(metadata), is(false)); } /** @@ -54,7 +58,9 @@ public class RepositoryConfigurationExtensionSupportUnitTests { */ @Test public void considersRepositoryWithAnnotatedTypeStrictMatch() { - assertThat(extension.isStrictRepositoryCandidate(AnnotatedTypeRepository.class), is(true)); + + RepositoryMetadata metadata = AbstractRepositoryMetadata.getMetadata(AnnotatedTypeRepository.class); + assertThat(extension.isStrictRepositoryCandidate(metadata), is(true)); } /** @@ -62,7 +68,9 @@ public class RepositoryConfigurationExtensionSupportUnitTests { */ @Test public void considersRepositoryInterfaceExtendingStoreInterfaceStrictMatch() { - assertThat(extension.isStrictRepositoryCandidate(ExtendingInterface.class), is(true)); + + RepositoryMetadata metadata = AbstractRepositoryMetadata.getMetadata(ExtendingInterface.class); + assertThat(extension.isStrictRepositoryCandidate(metadata), is(true)); } /** @@ -99,12 +107,12 @@ public class RepositoryConfigurationExtensionSupportUnitTests { @Override protected Collection> getIdentifyingAnnotations() { - return Collections.> singleton(Primary.class); + return Collections.>singleton(Primary.class); } @Override protected Collection> getIdentifyingTypes() { - return Collections.> singleton(StoreInterface.class); + return Collections.>singleton(StoreInterface.class); } }