Skip to content

Commit 29a6688

Browse files
committed
DATAMONGO-1470 - AbstractMongoConfiguration now supports multiple base packages for @document scanning.
Introduced AbstractMongoConfiguration.getMappingBasePackages() to return multiple ones over the previously existing ….getMappingBasePackage(). The former is now used by the code triggering the scanning using what the latter returns by default.
1 parent b6e7683 commit 29a6688

File tree

4 files changed

+147
-13
lines changed

4 files changed

+147
-13
lines changed

spring-data-mongodb/src/main/java/org/springframework/data/mongodb/config/AbstractMongoConfiguration.java

Lines changed: 50 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
/*
2-
* Copyright 2011-2015 the original author or authors.
2+
* Copyright 2011-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.
@@ -15,6 +15,7 @@
1515
*/
1616
package org.springframework.data.mongodb.config;
1717

18+
import java.util.Collection;
1819
import java.util.Collections;
1920
import java.util.HashSet;
2021
import java.util.Set;
@@ -118,17 +119,33 @@ public MongoDbFactory mongoDbFactory() throws Exception {
118119
* Return the base package to scan for mapped {@link Document}s. Will return the package name of the configuration
119120
* class' (the concrete class, not this one here) by default. So if you have a {@code com.acme.AppConfig} extending
120121
* {@link AbstractMongoConfiguration} the base package will be considered {@code com.acme} unless the method is
121-
* overriden to implement alternate behaviour.
122+
* overridden to implement alternate behavior.
122123
*
123124
* @return the base package to scan for mapped {@link Document} classes or {@literal null} to not enable scanning for
124125
* entities.
126+
* @deprecated use {@link #getMappingBasePackages()} instead.
125127
*/
128+
@Deprecated
126129
protected String getMappingBasePackage() {
127130

128131
Package mappingBasePackage = getClass().getPackage();
129132
return mappingBasePackage == null ? null : mappingBasePackage.getName();
130133
}
131134

135+
/**
136+
* Returns the base packages to scan for MongoDB mapped entities at startup. Will return the package name of the
137+
* configuration class' (the concrete class, not this one here) by default. So if you have a
138+
* {@code com.acme.AppConfig} extending {@link AbstractMongoConfiguration} the base package will be considered
139+
* {@code com.acme} unless the method is overridden to implement alternate behavior.
140+
*
141+
* @return the base packages to scan for mapped {@link Document} classes or an empty collection to not enable scanning
142+
* for entities.
143+
* @since 1.10
144+
*/
145+
protected Collection<String> getMappingBasePackages() {
146+
return Collections.singleton(getMappingBasePackage());
147+
}
148+
132149
/**
133150
* Return {@link UserCredentials} to be used when connecting to the MongoDB instance or {@literal null} if none shall
134151
* be used.
@@ -204,26 +221,52 @@ public MappingMongoConverter mappingMongoConverter() throws Exception {
204221
}
205222

206223
/**
207-
* Scans the mapping base package for classes annotated with {@link Document}.
224+
* Scans the mapping base package for classes annotated with {@link Document}. By default, it scans for entities in
225+
* all packages returned by {@link #getMappingBasePackages()}.
208226
*
209-
* @see #getMappingBasePackage()
227+
* @see #getMappingBasePackages()
210228
* @return
211229
* @throws ClassNotFoundException
212230
*/
213231
protected Set<Class<?>> getInitialEntitySet() throws ClassNotFoundException {
214232

215-
String basePackage = getMappingBasePackage();
233+
Set<Class<?>> initialEntitySet = new HashSet<Class<?>>();
234+
235+
for (String basePackage : getMappingBasePackages()) {
236+
initialEntitySet.addAll(scanForEntities(basePackage));
237+
}
238+
239+
return initialEntitySet;
240+
}
241+
242+
/**
243+
* Scans the given base package for entities, i.e. MongoDB specific types annotated with {@link Document} and
244+
* {@link Persistent}.
245+
*
246+
* @param basePackage must not be {@literal null}.
247+
* @return
248+
* @throws ClassNotFoundException
249+
* @since 1.10
250+
*/
251+
protected Set<Class<?>> scanForEntities(String basePackage) throws ClassNotFoundException {
252+
253+
if (!StringUtils.hasText(basePackage)) {
254+
return Collections.emptySet();
255+
}
256+
216257
Set<Class<?>> initialEntitySet = new HashSet<Class<?>>();
217258

218259
if (StringUtils.hasText(basePackage)) {
260+
219261
ClassPathScanningCandidateComponentProvider componentProvider = new ClassPathScanningCandidateComponentProvider(
220262
false);
221263
componentProvider.addIncludeFilter(new AnnotationTypeFilter(Document.class));
222264
componentProvider.addIncludeFilter(new AnnotationTypeFilter(Persistent.class));
223265

224266
for (BeanDefinition candidate : componentProvider.findCandidateComponents(basePackage)) {
225-
initialEntitySet.add(ClassUtils.forName(candidate.getBeanClassName(),
226-
AbstractMongoConfiguration.class.getClassLoader()));
267+
268+
initialEntitySet
269+
.add(ClassUtils.forName(candidate.getBeanClassName(), AbstractMongoConfiguration.class.getClassLoader()));
227270
}
228271
}
229272

Lines changed: 26 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,26 @@
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 example.first;
17+
18+
import org.springframework.data.mongodb.core.mapping.Document;
19+
20+
/**
21+
* @author Oliver Gierke
22+
*/
23+
@Document
24+
public class First {
25+
26+
}
Lines changed: 26 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,26 @@
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 example.second;
17+
18+
import org.springframework.data.mongodb.core.mapping.Document;
19+
20+
/**
21+
* @author Oliver Gierke
22+
*/
23+
@Document
24+
public class Second {
25+
26+
}

spring-data-mongodb/src/test/java/org/springframework/data/mongodb/config/AbstractMongoConfigurationUnitTests.java

Lines changed: 45 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
/*
2-
* Copyright 2012-2013 the original author or authors.
2+
* Copyright 2012-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.
@@ -18,6 +18,13 @@
1818
import static org.hamcrest.Matchers.*;
1919
import static org.junit.Assert.*;
2020

21+
import example.first.First;
22+
import example.second.Second;
23+
24+
import java.util.Arrays;
25+
import java.util.Collection;
26+
import java.util.Set;
27+
2128
import org.junit.Rule;
2229
import org.junit.Test;
2330
import org.junit.rules.ExpectedException;
@@ -144,6 +151,20 @@ public void authenticationDatabaseShouldDefaultToNull() {
144151
assertThat(new SampleMongoConfiguration().getAuthenticationDatabaseName(), is(nullValue()));
145152
}
146153

154+
/**
155+
* @see DATAMONGO-1470
156+
*/
157+
@Test
158+
@SuppressWarnings("unchecked")
159+
public void allowsMultipleEntityBasePackages() throws ClassNotFoundException {
160+
161+
ConfigurationWithMultipleBasePackages config = new ConfigurationWithMultipleBasePackages();
162+
Set<Class<?>> entities = config.getInitialEntitySet();
163+
164+
assertThat(entities, hasSize(2));
165+
assertThat(entities, hasItems(First.class, Second.class));
166+
}
167+
147168
private static void assertScanningDisabled(final String value) throws ClassNotFoundException {
148169

149170
AbstractMongoConfiguration configuration = new SampleMongoConfiguration() {
@@ -173,9 +194,11 @@ public Mongo mongo() throws Exception {
173194
@Bean
174195
@Override
175196
public MappingMongoConverter mappingMongoConverter() throws Exception {
176-
MappingMongoConverter mmc = super.mappingMongoConverter();
177-
mmc.setTypeMapper(typeMapper());
178-
return mmc;
197+
198+
MappingMongoConverter converter = super.mappingMongoConverter();
199+
converter.setTypeMapper(typeMapper());
200+
201+
return converter;
179202
}
180203

181204
@Bean
@@ -184,8 +207,24 @@ public MongoTypeMapper typeMapper() {
184207
}
185208
}
186209

187-
@Document
188-
static class Entity {
210+
static class ConfigurationWithMultipleBasePackages extends AbstractMongoConfiguration {
189211

212+
@Override
213+
protected String getDatabaseName() {
214+
return "test";
215+
}
216+
217+
@Override
218+
public Mongo mongo() throws Exception {
219+
return new MongoClient();
220+
}
221+
222+
@Override
223+
protected Collection<String> getMappingBasePackages() {
224+
return Arrays.asList("example.first", "example.second");
225+
}
190226
}
227+
228+
@Document
229+
static class Entity {}
191230
}

0 commit comments

Comments
 (0)