diff --git a/src/main/java/org/springframework/data/repository/config/RepositoryConfigurationDelegate.java b/src/main/java/org/springframework/data/repository/config/RepositoryConfigurationDelegate.java index 950e504cb..6b0718d91 100644 --- a/src/main/java/org/springframework/data/repository/config/RepositoryConfigurationDelegate.java +++ b/src/main/java/org/springframework/data/repository/config/RepositoryConfigurationDelegate.java @@ -25,12 +25,11 @@ import org.springframework.beans.factory.support.AbstractBeanDefinition; import org.springframework.beans.factory.support.BeanDefinitionBuilder; import org.springframework.beans.factory.support.BeanDefinitionRegistry; import org.springframework.beans.factory.support.BeanNameGenerator; -import org.springframework.context.annotation.ClassPathScanningCandidateComponentProvider; import org.springframework.core.env.Environment; import org.springframework.core.env.EnvironmentCapable; import org.springframework.core.env.StandardEnvironment; import org.springframework.core.io.ResourceLoader; -import org.springframework.core.type.filter.AssignableTypeFilter; +import org.springframework.core.io.support.SpringFactoriesLoader; import org.springframework.data.repository.core.support.RepositoryFactorySupport; import org.springframework.util.Assert; @@ -48,7 +47,6 @@ public class RepositoryConfigurationDelegate { private static final String REPOSITORY_REGISTRATION = "Spring Data {} - Registering repository: {} - Interface: {} - Factory: {}"; private static final String MULTIPLE_MODULES = "Multiple Spring Data modules found, entering strict repository configuration mode!"; - private static final String MODULE_DETECTION_PACKAGE = "org.springframework.data.**.repository.support"; static final String FACTORY_BEAN_OBJECT_TYPE = "factoryBeanObjectType"; @@ -160,17 +158,13 @@ public class RepositoryConfigurationDelegate { */ private boolean multipleStoresDetected() { - ClassPathScanningCandidateComponentProvider scanner = new ClassPathScanningCandidateComponentProvider(false); - scanner.setEnvironment(environment); - scanner.setResourceLoader(resourceLoader); - scanner.addIncludeFilter(new AssignableTypeFilter(RepositoryFactorySupport.class)); - - if (scanner.findCandidateComponents(MODULE_DETECTION_PACKAGE).size() > 1) { + boolean multipleModulesFound = SpringFactoriesLoader + .loadFactoryNames(RepositoryFactorySupport.class, resourceLoader.getClassLoader()).size() > 1; + if (multipleModulesFound) { LOGGER.info(MULTIPLE_MODULES); - return true; } - return false; + return multipleModulesFound; } } diff --git a/src/main/java/org/springframework/data/web/config/EnableSpringDataWebSupport.java b/src/main/java/org/springframework/data/web/config/EnableSpringDataWebSupport.java index 3acf2f565..d895f8d8a 100644 --- a/src/main/java/org/springframework/data/web/config/EnableSpringDataWebSupport.java +++ b/src/main/java/org/springframework/data/web/config/EnableSpringDataWebSupport.java @@ -23,16 +23,14 @@ import java.lang.annotation.Target; import java.util.ArrayList; import java.util.List; -import org.springframework.beans.factory.config.BeanDefinition; import org.springframework.context.EnvironmentAware; import org.springframework.context.ResourceLoaderAware; -import org.springframework.context.annotation.ClassPathScanningCandidateComponentProvider; import org.springframework.context.annotation.Import; import org.springframework.context.annotation.ImportSelector; import org.springframework.core.env.Environment; import org.springframework.core.io.ResourceLoader; +import org.springframework.core.io.support.SpringFactoriesLoader; import org.springframework.core.type.AnnotationMetadata; -import org.springframework.core.type.filter.AnnotationTypeFilter; import org.springframework.data.querydsl.QueryDslUtils; import org.springframework.data.web.PageableHandlerMethodArgumentResolver; import org.springframework.util.ClassUtils; @@ -124,15 +122,8 @@ public @interface EnableSpringDataWebSupport { : SpringDataWebConfiguration.class.getName()); if (JACKSON_PRESENT) { - - ClassPathScanningCandidateComponentProvider provider = new ClassPathScanningCandidateComponentProvider(false); - provider.setEnvironment(environment); - provider.setResourceLoader(resourceLoader); - provider.addIncludeFilter(new AnnotationTypeFilter(SpringDataWebConfigurationMixin.class)); - - for (BeanDefinition definition : provider.findCandidateComponents("org.springframework.data")) { - imports.add(definition.getBeanClassName()); - } + imports.addAll( + SpringFactoriesLoader.loadFactoryNames(SpringDataJacksonModules.class, resourceLoader.getClassLoader())); } return imports.toArray(new String[imports.size()]); diff --git a/src/main/java/org/springframework/data/web/config/SpringDataJacksonConfiguration.java b/src/main/java/org/springframework/data/web/config/SpringDataJacksonConfiguration.java index 3fd412e50..5d9d60334 100644 --- a/src/main/java/org/springframework/data/web/config/SpringDataJacksonConfiguration.java +++ b/src/main/java/org/springframework/data/web/config/SpringDataJacksonConfiguration.java @@ -1,5 +1,5 @@ /* - * Copyright 2014-2015 the original author or authors. + * Copyright 2014-2016 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. @@ -23,8 +23,7 @@ import org.springframework.data.geo.GeoModule; * * @author Oliver Gierke */ -@SpringDataWebConfigurationMixin -public class SpringDataJacksonConfiguration { +public class SpringDataJacksonConfiguration implements SpringDataJacksonModules { @Bean public GeoModule jacksonGeoModule() { diff --git a/src/main/java/org/springframework/data/web/config/SpringDataJacksonModules.java b/src/main/java/org/springframework/data/web/config/SpringDataJacksonModules.java new file mode 100644 index 000000000..ef030a84b --- /dev/null +++ b/src/main/java/org/springframework/data/web/config/SpringDataJacksonModules.java @@ -0,0 +1,27 @@ +/* + * Copyright 2016 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.data.web.config; + +import com.fasterxml.jackson.databind.ObjectMapper; + +/** + * Marker interface to describe configuration classes that ship Jackson modules that are supposed to be added to the + * Jackson {@link ObjectMapper} configured for {@link EnableSpringDataWebSupport}. + * + * @author Oliver Gierke + * @since 1.13 + */ +public interface SpringDataJacksonModules {} diff --git a/src/main/java/org/springframework/data/web/config/SpringDataWebConfigurationMixin.java b/src/main/java/org/springframework/data/web/config/SpringDataWebConfigurationMixin.java deleted file mode 100644 index 15b615245..000000000 --- a/src/main/java/org/springframework/data/web/config/SpringDataWebConfigurationMixin.java +++ /dev/null @@ -1,41 +0,0 @@ -/* - * Copyright 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.data.web.config; - -import java.lang.annotation.Documented; -import java.lang.annotation.ElementType; -import java.lang.annotation.Retention; -import java.lang.annotation.RetentionPolicy; -import java.lang.annotation.Target; - -import org.springframework.context.annotation.Configuration; -import org.springframework.data.web.config.EnableSpringDataWebSupport.SpringDataWebConfigurationImportSelector; - -/** - * Annotation to be able to scan for additional Spring Data configuration classes to contribute to the web integration. - * - * @author Oliver Gierke - * @since 1.10 - * @soundtrack Selah Sue - This World (Selah Sue) - * @see SpringDataJacksonConfiguration - * @see SpringDataWebConfigurationImportSelector - */ -@Retention(RetentionPolicy.RUNTIME) -@Documented -@Configuration -@Target({ ElementType.TYPE, ElementType.ANNOTATION_TYPE }) -public @interface SpringDataWebConfigurationMixin { -} diff --git a/src/main/resources/META-INF/spring.factories b/src/main/resources/META-INF/spring.factories new file mode 100644 index 000000000..5b6d502f7 --- /dev/null +++ b/src/main/resources/META-INF/spring.factories @@ -0,0 +1 @@ +org.springframework.data.web.config.SpringDataJacksonModules=org.springframework.data.web.config.SpringDataJacksonConfiguration diff --git a/src/test/java/org/springframework/data/web/config/SampleMixin.java b/src/test/java/org/springframework/data/web/config/SampleMixin.java index 26e8001b3..019e73d74 100644 --- a/src/test/java/org/springframework/data/web/config/SampleMixin.java +++ b/src/test/java/org/springframework/data/web/config/SampleMixin.java @@ -20,8 +20,7 @@ import org.springframework.context.annotation.Bean; /** * @author Oliver Gierke */ -@SpringDataWebConfigurationMixin -public class SampleMixin { +public class SampleMixin implements SpringDataJacksonModules { @Bean String sampleBean() { diff --git a/src/test/resources/META-INF/spring.factories b/src/test/resources/META-INF/spring.factories new file mode 100644 index 000000000..81d1c0f82 --- /dev/null +++ b/src/test/resources/META-INF/spring.factories @@ -0,0 +1 @@ +org.springframework.data.web.config.SpringDataJacksonModules=org.springframework.data.web.config.SampleMixin