Skip to content

Commit 76d1995

Browse files
committed
DATACMNS-952 - Switched from component scanning to SpringFactoriesLoader for internal extension points.
Both the configuration code looking up Spring Data specific Jackson modules as well as the code detecting whether we have multiple Spring Data modules on the classpath used component scanning. That can have quite significant impact on startup times. This commit replaces the classpath scanning with the use of SpringFactoriesLoader that now requires modules that want to extend the behavior of Spring Data's web configuration or indicate a repository implementation being present by shipping a file called META-INF/spring.factories. Spring Data relies on the following keys: - org.springframework.data.web.config.SpringDataJacksonModules - list the Spring configuration classes that will expose additional Jackson modules that are supposed to be registered for Spring Data's Jackson web support - org.springframework.data.repository.core.support.RepositoryFactorySupport - list the Spring Data repository factory implementation class that implements repository support for your module. The general detection and configuration mechanism for user repositories is not affected by this. Currently Spring Data only uses the pure number of different entries for that key to switch into strict configuration mode in case we find more than one entry.
1 parent 8d67c84 commit 76d1995

File tree

8 files changed

+40
-69
lines changed

8 files changed

+40
-69
lines changed

src/main/java/org/springframework/data/repository/config/RepositoryConfigurationDelegate.java

Lines changed: 5 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -25,12 +25,11 @@
2525
import org.springframework.beans.factory.support.BeanDefinitionBuilder;
2626
import org.springframework.beans.factory.support.BeanDefinitionRegistry;
2727
import org.springframework.beans.factory.support.BeanNameGenerator;
28-
import org.springframework.context.annotation.ClassPathScanningCandidateComponentProvider;
2928
import org.springframework.core.env.Environment;
3029
import org.springframework.core.env.EnvironmentCapable;
3130
import org.springframework.core.env.StandardEnvironment;
3231
import org.springframework.core.io.ResourceLoader;
33-
import org.springframework.core.type.filter.AssignableTypeFilter;
32+
import org.springframework.core.io.support.SpringFactoriesLoader;
3433
import org.springframework.data.repository.core.support.RepositoryFactorySupport;
3534
import org.springframework.util.Assert;
3635

@@ -48,7 +47,6 @@ public class RepositoryConfigurationDelegate {
4847

4948
private static final String REPOSITORY_REGISTRATION = "Spring Data {} - Registering repository: {} - Interface: {} - Factory: {}";
5049
private static final String MULTIPLE_MODULES = "Multiple Spring Data modules found, entering strict repository configuration mode!";
51-
private static final String MODULE_DETECTION_PACKAGE = "org.springframework.data.**.repository.support";
5250

5351
static final String FACTORY_BEAN_OBJECT_TYPE = "factoryBeanObjectType";
5452

@@ -160,17 +158,13 @@ public List<BeanComponentDefinition> registerRepositoriesIn(BeanDefinitionRegist
160158
*/
161159
private boolean multipleStoresDetected() {
162160

163-
ClassPathScanningCandidateComponentProvider scanner = new ClassPathScanningCandidateComponentProvider(false);
164-
scanner.setEnvironment(environment);
165-
scanner.setResourceLoader(resourceLoader);
166-
scanner.addIncludeFilter(new AssignableTypeFilter(RepositoryFactorySupport.class));
167-
168-
if (scanner.findCandidateComponents(MODULE_DETECTION_PACKAGE).size() > 1) {
161+
boolean multipleModulesFound = SpringFactoriesLoader
162+
.loadFactoryNames(RepositoryFactorySupport.class, resourceLoader.getClassLoader()).size() > 1;
169163

164+
if (multipleModulesFound) {
170165
LOGGER.info(MULTIPLE_MODULES);
171-
return true;
172166
}
173167

174-
return false;
168+
return multipleModulesFound;
175169
}
176170
}

src/main/java/org/springframework/data/web/config/EnableSpringDataWebSupport.java

Lines changed: 3 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -23,16 +23,14 @@
2323
import java.util.ArrayList;
2424
import java.util.List;
2525

26-
import org.springframework.beans.factory.config.BeanDefinition;
2726
import org.springframework.context.EnvironmentAware;
2827
import org.springframework.context.ResourceLoaderAware;
29-
import org.springframework.context.annotation.ClassPathScanningCandidateComponentProvider;
3028
import org.springframework.context.annotation.Import;
3129
import org.springframework.context.annotation.ImportSelector;
3230
import org.springframework.core.env.Environment;
3331
import org.springframework.core.io.ResourceLoader;
32+
import org.springframework.core.io.support.SpringFactoriesLoader;
3433
import org.springframework.core.type.AnnotationMetadata;
35-
import org.springframework.core.type.filter.AnnotationTypeFilter;
3634
import org.springframework.data.querydsl.QueryDslUtils;
3735
import org.springframework.data.web.PageableHandlerMethodArgumentResolver;
3836
import org.springframework.util.ClassUtils;
@@ -124,15 +122,8 @@ public String[] selectImports(AnnotationMetadata importingClassMetadata) {
124122
: SpringDataWebConfiguration.class.getName());
125123

126124
if (JACKSON_PRESENT) {
127-
128-
ClassPathScanningCandidateComponentProvider provider = new ClassPathScanningCandidateComponentProvider(false);
129-
provider.setEnvironment(environment);
130-
provider.setResourceLoader(resourceLoader);
131-
provider.addIncludeFilter(new AnnotationTypeFilter(SpringDataWebConfigurationMixin.class));
132-
133-
for (BeanDefinition definition : provider.findCandidateComponents("org.springframework.data")) {
134-
imports.add(definition.getBeanClassName());
135-
}
125+
imports.addAll(
126+
SpringFactoriesLoader.loadFactoryNames(SpringDataJacksonModules.class, resourceLoader.getClassLoader()));
136127
}
137128

138129
return imports.toArray(new String[imports.size()]);

src/main/java/org/springframework/data/web/config/SpringDataJacksonConfiguration.java

Lines changed: 2 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
/*
2-
* Copyright 2014-2015 the original author or authors.
2+
* Copyright 2014-2016 the original author or authors.
33
*
44
* Licensed under the Apache License, Version 2.0 (the "License");
55
* you may not use this file except in compliance with the License.
@@ -23,8 +23,7 @@
2323
*
2424
* @author Oliver Gierke
2525
*/
26-
@SpringDataWebConfigurationMixin
27-
public class SpringDataJacksonConfiguration {
26+
public class SpringDataJacksonConfiguration implements SpringDataJacksonModules {
2827

2928
@Bean
3029
public GeoModule jacksonGeoModule() {
Lines changed: 27 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,27 @@
1+
/*
2+
* Copyright 2016 the original author or authors.
3+
*
4+
* Licensed under the Apache License, Version 2.0 (the "License");
5+
* you may not use this file except in compliance with the License.
6+
* You may obtain a copy of the License at
7+
*
8+
* http://www.apache.org/licenses/LICENSE-2.0
9+
*
10+
* Unless required by applicable law or agreed to in writing, software
11+
* distributed under the License is distributed on an "AS IS" BASIS,
12+
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13+
* See the License for the specific language governing permissions and
14+
* limitations under the License.
15+
*/
16+
package org.springframework.data.web.config;
17+
18+
import com.fasterxml.jackson.databind.ObjectMapper;
19+
20+
/**
21+
* Marker interface to describe configuration classes that ship Jackson modules that are supposed to be added to the
22+
* Jackson {@link ObjectMapper} configured for {@link EnableSpringDataWebSupport}.
23+
*
24+
* @author Oliver Gierke
25+
* @since 1.13
26+
*/
27+
public interface SpringDataJacksonModules {}

src/main/java/org/springframework/data/web/config/SpringDataWebConfigurationMixin.java

Lines changed: 0 additions & 41 deletions
This file was deleted.
Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
org.springframework.data.web.config.SpringDataJacksonModules=org.springframework.data.web.config.SpringDataJacksonConfiguration

src/test/java/org/springframework/data/web/config/SampleMixin.java

Lines changed: 1 addition & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -20,8 +20,7 @@
2020
/**
2121
* @author Oliver Gierke
2222
*/
23-
@SpringDataWebConfigurationMixin
24-
public class SampleMixin {
23+
public class SampleMixin implements SpringDataJacksonModules {
2524

2625
@Bean
2726
String sampleBean() {
Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
org.springframework.data.web.config.SpringDataJacksonModules=org.springframework.data.web.config.SampleMixin

0 commit comments

Comments
 (0)