diff --git a/spring-data-mongodb/src/main/java/org/springframework/data/mongodb/config/AbstractMongoConfiguration.java b/spring-data-mongodb/src/main/java/org/springframework/data/mongodb/config/AbstractMongoConfiguration.java index bdd9032e0..4547166f2 100644 --- a/spring-data-mongodb/src/main/java/org/springframework/data/mongodb/config/AbstractMongoConfiguration.java +++ b/spring-data-mongodb/src/main/java/org/springframework/data/mongodb/config/AbstractMongoConfiguration.java @@ -1,5 +1,5 @@ /* - * Copyright 2010-2011 the original author or authors. + * Copyright 2011-2012 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. @@ -15,88 +15,176 @@ */ package org.springframework.data.mongodb.config; +import java.util.Collections; import java.util.HashSet; import java.util.Set; -import com.mongodb.Mongo; import org.springframework.beans.factory.config.BeanDefinition; import org.springframework.context.annotation.Bean; import org.springframework.context.annotation.ClassPathScanningCandidateComponentProvider; import org.springframework.context.annotation.Configuration; +import org.springframework.core.convert.converter.Converter; import org.springframework.core.type.filter.AnnotationTypeFilter; import org.springframework.data.annotation.Persistent; import org.springframework.data.authentication.UserCredentials; -import org.springframework.data.mongodb.MongoDbFactory; import org.springframework.data.mongodb.core.MongoTemplate; import org.springframework.data.mongodb.core.SimpleMongoDbFactory; +import org.springframework.data.mongodb.core.convert.CustomConversions; import org.springframework.data.mongodb.core.convert.MappingMongoConverter; import org.springframework.data.mongodb.core.mapping.Document; import org.springframework.data.mongodb.core.mapping.MongoMappingContext; import org.springframework.util.ClassUtils; import org.springframework.util.StringUtils; +import com.mongodb.Mongo; + +/** + * Base class for Spring Data Mongo configuration using JavaConfig. + * + * @author Mark Pollack + * @author Oliver Gierke + */ @Configuration public abstract class AbstractMongoConfiguration { - public abstract String getDatabaseName(); + /** + * Return the name of the database to connect to. + * + * @return must not be {@literal null}. + */ + protected abstract String getDatabaseName(); + /** + * Return the {@link Mongo} instance to connect to. + * + * @return + * @throws Exception + */ @Bean public abstract Mongo mongo() throws Exception; + /** + * Creates a {@link MongoTemplate}. + * + * @return + * @throws Exception + */ @Bean public MongoTemplate mongoTemplate() throws Exception { return new MongoTemplate(mongoDbFactory(), mappingMongoConverter()); } + /** + * Creates a {@link SimpleMongoDbFactory} to be used by the {@link MongoTemplate}. Will use the {@link Mongo} instance + * configured in {@link #mongo()}. + * + * @see #mongo() + * @see #mongoTemplate() + * @return + * @throws Exception + */ @Bean - public MongoDbFactory mongoDbFactory() throws Exception { - if (getUserCredentials() == null) { + public SimpleMongoDbFactory mongoDbFactory() throws Exception { + + UserCredentials creadentials = getUserCredentials(); + + if (creadentials == null) { return new SimpleMongoDbFactory(mongo(), getDatabaseName()); } else { - return new SimpleMongoDbFactory(mongo(), getDatabaseName(), getUserCredentials()); + return new SimpleMongoDbFactory(mongo(), getDatabaseName(), creadentials); } } - public String getMappingBasePackage() { - return ""; + /** + * Return the base package to scan for mapped {@link Document}s. + * + * @return + */ + protected String getMappingBasePackage() { + return null; } - public UserCredentials getUserCredentials() { + /** + * Return {@link UserCredentials} to be used when connecting to the MongoDB instance or {@literal null} if none shall + * be used. + * + * @return + */ + protected UserCredentials getUserCredentials() { return null; } + /** + * Creates a {@link MongoMappingContext} equipped with entity classes scanned from the mapping base package. + * + * @see #getMappingBasePackage() + * @return + * @throws ClassNotFoundException + */ @Bean - public MongoMappingContext mongoMappingContext() throws ClassNotFoundException, LinkageError { + public MongoMappingContext mongoMappingContext() throws ClassNotFoundException { + MongoMappingContext mappingContext = new MongoMappingContext(); - String basePackage = getMappingBasePackage(); - if (StringUtils.hasText(basePackage)) { - ClassPathScanningCandidateComponentProvider componentProvider = new ClassPathScanningCandidateComponentProvider( - false); - componentProvider.addIncludeFilter(new AnnotationTypeFilter(Document.class)); - componentProvider.addIncludeFilter(new AnnotationTypeFilter(Persistent.class)); + mappingContext.setInitialEntitySet(getInitialEntitySet()); + mappingContext.setSimpleTypeHolder(customConversions().getSimpleTypeHolder()); + mappingContext.afterPropertiesSet(); - Set> initialEntitySet = new HashSet>(); - for (BeanDefinition candidate : componentProvider.findCandidateComponents(basePackage)) { - initialEntitySet.add(ClassUtils.forName(candidate.getBeanClassName(), mappingContext.getClass() - .getClassLoader())); - } - mappingContext.setInitialEntitySet(initialEntitySet); - } return mappingContext; } + /** + * Register custom {@link Converter}s in a {@link CustomConversions} object if required. These + * {@link CustomConversions} will be registered with the {@link #mappingMongoConverter()} and + * {@link #mongoMappingContext()}. Returns an empty {@link CustomConversions} instance by default. + * + * @return must not be {@literal null}. + */ + @Bean + public CustomConversions customConversions() { + return new CustomConversions(Collections.emptyList()); + } + + /** + * Creates a {@link MappingMongoConverter} using the configured {@link #mongoDbFactory()} and + * {@link #mongoMappingContext()}. Will get {@link #customConversions()} applied. + * + * @see #customConversions() + * @see #mongoMappingContext() + * @see #mongoDbFactory() + * @return + * @throws Exception + */ @Bean public MappingMongoConverter mappingMongoConverter() throws Exception { MappingMongoConverter converter = new MappingMongoConverter(mongoDbFactory(), mongoMappingContext()); - afterMappingMongoConverterCreation(converter); + converter.setCustomConversions(customConversions()); return converter; } /** - * Hook that allows post-processing after the MappingMongoConverter has been successfully created. + * Scans the mapping base package for classes annotated with {@link Document}. * - * @param converter + * @see #getMappingBasePackage() + * @return + * @throws ClassNotFoundException */ - protected void afterMappingMongoConverterCreation(MappingMongoConverter converter) { + protected Set> getInitialEntitySet() throws ClassNotFoundException { + + String basePackage = getMappingBasePackage(); + Set> initialEntitySet = new HashSet>(); + + if (StringUtils.hasText(basePackage)) { + ClassPathScanningCandidateComponentProvider componentProvider = new ClassPathScanningCandidateComponentProvider( + false); + componentProvider.addIncludeFilter(new AnnotationTypeFilter(Document.class)); + componentProvider.addIncludeFilter(new AnnotationTypeFilter(Persistent.class)); + + for (BeanDefinition candidate : componentProvider.findCandidateComponents(basePackage)) { + initialEntitySet.add(ClassUtils.forName(candidate.getBeanClassName(), + AbstractMongoConfiguration.class.getClassLoader())); + } + } + + return initialEntitySet; } } diff --git a/spring-data-mongodb/src/test/java/org/springframework/data/mongodb/core/TestMongoConfiguration.java b/spring-data-mongodb/src/test/java/org/springframework/data/mongodb/core/TestMongoConfiguration.java index c4f049bb5..2f393b118 100644 --- a/spring-data-mongodb/src/test/java/org/springframework/data/mongodb/core/TestMongoConfiguration.java +++ b/spring-data-mongodb/src/test/java/org/springframework/data/mongodb/core/TestMongoConfiguration.java @@ -2,12 +2,14 @@ package org.springframework.data.mongodb.core; import java.util.ArrayList; import java.util.List; -import com.mongodb.Mongo; + import org.springframework.context.annotation.Bean; import org.springframework.core.convert.converter.Converter; import org.springframework.data.mongodb.config.AbstractMongoConfiguration; import org.springframework.data.mongodb.core.convert.CustomConversions; -import org.springframework.data.mongodb.core.convert.MappingMongoConverter; +import org.springframework.data.mongodb.core.mapping.MongoMappingContext; + +import com.mongodb.Mongo; public class TestMongoConfiguration extends AbstractMongoConfiguration { @@ -24,15 +26,15 @@ public class TestMongoConfiguration extends AbstractMongoConfiguration { @Override public String getMappingBasePackage() { - return "org.springframework.data.mongodb.core.core.mapping"; + return MongoMappingContext.class.getPackage().getName(); } @Override - protected void afterMappingMongoConverterCreation(MappingMongoConverter converter) { + public CustomConversions customConversions() { + List> converters = new ArrayList>(); converters.add(new org.springframework.data.mongodb.core.PersonReadConverter()); converters.add(new org.springframework.data.mongodb.core.PersonWriteConverter()); - converter.setCustomConversions(new CustomConversions(converters)); + return new CustomConversions(converters); } - }