Setup MongoMappingContext setInitialEntitySet

Update MongoDataAutoConfiguration to set the MongoMappingContext
initialEntitySet by scanning for @Document or @Persistent classes
from AutoConfigurationPackages.

Fixes gh-2107
pull/2111/head
Oliver Gierke 10 years ago committed by Phillip Webb
parent a27217ae43
commit 034ce0ad89

@ -17,19 +17,30 @@
package org.springframework.boot.autoconfigure.mongo; package org.springframework.boot.autoconfigure.mongo;
import java.net.UnknownHostException; import java.net.UnknownHostException;
import java.util.Collection;
import java.util.Collections;
import java.util.HashSet;
import java.util.Set;
import org.springframework.beans.factory.BeanFactory; import org.springframework.beans.factory.BeanFactory;
import org.springframework.beans.factory.NoSuchBeanDefinitionException; import org.springframework.beans.factory.NoSuchBeanDefinitionException;
import org.springframework.beans.factory.annotation.Autowired; import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.config.BeanDefinition;
import org.springframework.boot.autoconfigure.AutoConfigurationPackages;
import org.springframework.boot.autoconfigure.AutoConfigureAfter; import org.springframework.boot.autoconfigure.AutoConfigureAfter;
import org.springframework.boot.autoconfigure.EnableAutoConfiguration; import org.springframework.boot.autoconfigure.EnableAutoConfiguration;
import org.springframework.boot.autoconfigure.condition.ConditionalOnClass; import org.springframework.boot.autoconfigure.condition.ConditionalOnClass;
import org.springframework.boot.autoconfigure.condition.ConditionalOnMissingBean; import org.springframework.boot.autoconfigure.condition.ConditionalOnMissingBean;
import org.springframework.boot.context.properties.EnableConfigurationProperties; import org.springframework.boot.context.properties.EnableConfigurationProperties;
import org.springframework.context.annotation.Bean; import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.ClassPathScanningCandidateComponentProvider;
import org.springframework.context.annotation.Configuration; import org.springframework.context.annotation.Configuration;
import org.springframework.core.env.Environment;
import org.springframework.core.io.ResourceLoader;
import org.springframework.core.type.filter.AnnotationTypeFilter;
import org.springframework.dao.DataAccessException; import org.springframework.dao.DataAccessException;
import org.springframework.dao.support.PersistenceExceptionTranslator; import org.springframework.dao.support.PersistenceExceptionTranslator;
import org.springframework.data.annotation.Persistent;
import org.springframework.data.authentication.UserCredentials; import org.springframework.data.authentication.UserCredentials;
import org.springframework.data.mongodb.MongoDbFactory; import org.springframework.data.mongodb.MongoDbFactory;
import org.springframework.data.mongodb.core.MongoTemplate; import org.springframework.data.mongodb.core.MongoTemplate;
@ -39,9 +50,11 @@ import org.springframework.data.mongodb.core.convert.DbRefResolver;
import org.springframework.data.mongodb.core.convert.DefaultDbRefResolver; import org.springframework.data.mongodb.core.convert.DefaultDbRefResolver;
import org.springframework.data.mongodb.core.convert.MappingMongoConverter; import org.springframework.data.mongodb.core.convert.MappingMongoConverter;
import org.springframework.data.mongodb.core.convert.MongoConverter; import org.springframework.data.mongodb.core.convert.MongoConverter;
import org.springframework.data.mongodb.core.mapping.Document;
import org.springframework.data.mongodb.core.mapping.MongoMappingContext; import org.springframework.data.mongodb.core.mapping.MongoMappingContext;
import org.springframework.data.mongodb.gridfs.GridFsTemplate; import org.springframework.data.mongodb.gridfs.GridFsTemplate;
import org.springframework.util.Assert; import org.springframework.util.Assert;
import org.springframework.util.ClassUtils;
import org.springframework.util.StringUtils; import org.springframework.util.StringUtils;
import com.mongodb.DB; import com.mongodb.DB;
@ -71,6 +84,12 @@ public class MongoDataAutoConfiguration {
@Autowired @Autowired
private MongoProperties properties; private MongoProperties properties;
@Autowired
private Environment environment;
@Autowired
private ResourceLoader resourceLoader;
@Bean @Bean
@ConditionalOnMissingBean @ConditionalOnMissingBean
public MongoDbFactory mongoDbFactory(Mongo mongo) throws Exception { public MongoDbFactory mongoDbFactory(Mongo mongo) throws Exception {
@ -111,8 +130,42 @@ public class MongoDataAutoConfiguration {
@Bean @Bean
@ConditionalOnMissingBean @ConditionalOnMissingBean
public MongoMappingContext mongoMappingContext() { public MongoMappingContext mongoMappingContext(BeanFactory beanFactory)
return new MongoMappingContext(); throws ClassNotFoundException {
MongoMappingContext context = new MongoMappingContext();
context.setInitialEntitySet(getInitialEntitySet(beanFactory));
return context;
}
private Set<Class<?>> getInitialEntitySet(BeanFactory beanFactory)
throws ClassNotFoundException {
Set<Class<?>> entitySet = new HashSet<Class<?>>();
ClassPathScanningCandidateComponentProvider scanner = new ClassPathScanningCandidateComponentProvider(
false);
scanner.setEnvironment(this.environment);
scanner.setResourceLoader(this.resourceLoader);
scanner.addIncludeFilter(new AnnotationTypeFilter(Document.class));
scanner.addIncludeFilter(new AnnotationTypeFilter(Persistent.class));
for (String basePackage : getMappingBasePackages(beanFactory)) {
if (StringUtils.hasText(basePackage)) {
for (BeanDefinition candidate : scanner
.findCandidateComponents(basePackage)) {
entitySet.add(ClassUtils.forName(candidate.getBeanClassName(),
MongoDataAutoConfiguration.class.getClassLoader()));
}
}
}
return entitySet;
}
private static Collection<String> getMappingBasePackages(BeanFactory beanFactory) {
try {
return AutoConfigurationPackages.get(beanFactory);
}
catch (IllegalStateException ex) {
// no auto-configuration package registered yet
return Collections.emptyList();
}
} }
@Bean @Bean

@ -17,10 +17,14 @@
package org.springframework.boot.autoconfigure.mongo; package org.springframework.boot.autoconfigure.mongo;
import java.util.Arrays; import java.util.Arrays;
import java.util.Set;
import org.hamcrest.Matchers;
import org.junit.After; import org.junit.After;
import org.junit.Test; import org.junit.Test;
import org.springframework.boot.autoconfigure.AutoConfigurationPackages;
import org.springframework.boot.autoconfigure.PropertyPlaceholderAutoConfiguration; import org.springframework.boot.autoconfigure.PropertyPlaceholderAutoConfiguration;
import org.springframework.boot.autoconfigure.data.mongo.city.City;
import org.springframework.boot.test.EnvironmentTestUtils; import org.springframework.boot.test.EnvironmentTestUtils;
import org.springframework.context.annotation.AnnotationConfigApplicationContext; import org.springframework.context.annotation.AnnotationConfigApplicationContext;
import org.springframework.context.annotation.Bean; import org.springframework.context.annotation.Bean;
@ -28,17 +32,22 @@ import org.springframework.context.annotation.Configuration;
import org.springframework.core.convert.converter.Converter; import org.springframework.core.convert.converter.Converter;
import org.springframework.data.mongodb.core.MongoTemplate; import org.springframework.data.mongodb.core.MongoTemplate;
import org.springframework.data.mongodb.core.convert.CustomConversions; import org.springframework.data.mongodb.core.convert.CustomConversions;
import org.springframework.data.mongodb.core.mapping.MongoMappingContext;
import org.springframework.data.mongodb.gridfs.GridFsTemplate; import org.springframework.data.mongodb.gridfs.GridFsTemplate;
import org.springframework.test.util.ReflectionTestUtils;
import com.mongodb.Mongo; import com.mongodb.Mongo;
import static org.hamcrest.Matchers.hasSize;
import static org.junit.Assert.assertEquals; import static org.junit.Assert.assertEquals;
import static org.junit.Assert.assertThat;
import static org.junit.Assert.assertTrue; import static org.junit.Assert.assertTrue;
/** /**
* Tests for {@link MongoDataAutoConfiguration}. * Tests for {@link MongoDataAutoConfiguration}.
* *
* @author Josh Long * @author Josh Long
* @author Oliver Gierke
*/ */
public class MongoDataAutoConfigurationTests { public class MongoDataAutoConfigurationTests {
@ -82,6 +91,27 @@ public class MongoDataAutoConfigurationTests {
.canConvert(Mongo.class, Boolean.class)); .canConvert(Mongo.class, Boolean.class));
} }
@Test
public void usesAutoConfigurationPackageToPickUpDocumentTypes() {
this.context = new AnnotationConfigApplicationContext();
String cityPackage = City.class.getPackage().getName();
AutoConfigurationPackages.register(this.context, cityPackage);
this.context.register(MongoAutoConfiguration.class,
MongoDataAutoConfiguration.class);
this.context.refresh();
assertDomainTypesDiscovered(this.context.getBean(MongoMappingContext.class),
City.class);
}
@SuppressWarnings({ "unchecked", "rawtypes" })
private static void assertDomainTypesDiscovered(MongoMappingContext mappingContext,
Class<?>... types) {
Set<Class> initialEntitySet = (Set<Class>) ReflectionTestUtils.getField(
mappingContext, "initialEntitySet");
assertThat(initialEntitySet, hasSize(types.length));
assertThat(initialEntitySet, Matchers.<Class> hasItems(types));
}
@Configuration @Configuration
static class CustomConversionsConfig { static class CustomConversionsConfig {
@ -89,7 +119,6 @@ public class MongoDataAutoConfigurationTests {
public CustomConversions customConversions() { public CustomConversions customConversions() {
return new CustomConversions(Arrays.asList(new MyConverter())); return new CustomConversions(Arrays.asList(new MyConverter()));
} }
} }
private static class MyConverter implements Converter<Mongo, Boolean> { private static class MyConverter implements Converter<Mongo, Boolean> {
@ -100,4 +129,5 @@ public class MongoDataAutoConfigurationTests {
} }
} }
} }

Loading…
Cancel
Save