Skip to content

Commit 8ec0dee

Browse files
mp911dechristophstrobl
authored andcommitted
DATAMONGO-1444 - Add support for RxJava wrapper types and slice queries.
Reactive MongoDB repository can now be composed from Project Reactor and RxJava types for method arguments and return types. Query methods and methods from the base/implementation classes can be invoked with a conversion of input/output types.
1 parent a12da04 commit 8ec0dee

File tree

94 files changed

+15582
-482
lines changed

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

94 files changed

+15582
-482
lines changed

pom.xml

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -30,6 +30,7 @@
3030
<dist.id>spring-data-mongodb</dist.id>
3131
<springdata.commons>2.0.0.DATACMNS-836-SNAPSHOT</springdata.commons>
3232
<mongo>3.2.2</mongo>
33+
<mongo.reactivestreams>1.2.0</mongo.reactivestreams>
3334
</properties>
3435

3536
<developers>

spring-data-mongodb-cross-store/pom.xml

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -51,6 +51,14 @@
5151
<version>2.0.0.DATAMONGO-1444-SNAPSHOT</version>
5252
</dependency>
5353

54+
<!-- reactive -->
55+
<dependency>
56+
<groupId>io.projectreactor</groupId>
57+
<artifactId>reactor-core</artifactId>
58+
<version>${reactor}</version>
59+
<optional>true</optional>
60+
</dependency>
61+
5462
<dependency>
5563
<groupId>org.aspectj</groupId>
5664
<artifactId>aspectjrt</artifactId>

spring-data-mongodb/pom.xml

Lines changed: 49 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -19,6 +19,7 @@
1919
<objenesis>1.3</objenesis>
2020
<equalsverifier>1.5</equalsverifier>
2121
<mongo>3.3.0</mongo>
22+
<spring>5.0.0.BUILD-SNAPSHOT</spring>
2223
</properties>
2324

2425
<dependencies>
@@ -79,6 +80,52 @@
7980
<optional>true</optional>
8081
</dependency>
8182

83+
<!-- reactive -->
84+
<dependency>
85+
<groupId>org.mongodb</groupId>
86+
<artifactId>mongodb-driver-reactivestreams</artifactId>
87+
<version>${mongo.reactivestreams}</version>
88+
<optional>true</optional>
89+
</dependency>
90+
91+
<dependency>
92+
<groupId>org.mongodb</groupId>
93+
<artifactId>mongodb-driver-async</artifactId>
94+
<version>${mongo}</version>
95+
<optional>true</optional>
96+
<exclusions>
97+
<exclusion>
98+
<groupId>org.mongodb</groupId>
99+
<artifactId>mongodb-driver-core</artifactId>
100+
</exclusion>
101+
<exclusion>
102+
<groupId>org.mongodb</groupId>
103+
<artifactId>bson</artifactId>
104+
</exclusion>
105+
</exclusions>
106+
</dependency>
107+
108+
<dependency>
109+
<groupId>io.projectreactor</groupId>
110+
<artifactId>reactor-core</artifactId>
111+
<version>${reactor}</version>
112+
<optional>true</optional>
113+
</dependency>
114+
115+
<dependency>
116+
<groupId>io.reactivex</groupId>
117+
<artifactId>rxjava</artifactId>
118+
<version>${rxjava}</version>
119+
<optional>true</optional>
120+
</dependency>
121+
122+
<dependency>
123+
<groupId>io.reactivex</groupId>
124+
<artifactId>rxjava-reactive-streams</artifactId>
125+
<version>${rxjava-reactive-streams}</version>
126+
<optional>true</optional>
127+
</dependency>
128+
82129
<!-- CDI -->
83130
<dependency>
84131
<groupId>javax.enterprise</groupId>
@@ -213,9 +260,11 @@
213260
</includes>
214261
<excludes>
215262
<exclude>**/PerformanceTests.java</exclude>
263+
<exclude>**/ReactivePerformanceTests.java</exclude>
216264
</excludes>
217265
<systemPropertyVariables>
218266
<java.util.logging.config.file>src/test/resources/logging.properties</java.util.logging.config.file>
267+
<reactor.trace.cancel>true</reactor.trace.cancel>
219268
</systemPropertyVariables>
220269
<properties>
221270
<property>
Lines changed: 56 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,56 @@
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+
17+
package org.springframework.data.mongodb;
18+
19+
import org.springframework.dao.DataAccessException;
20+
import org.springframework.dao.support.PersistenceExceptionTranslator;
21+
import org.springframework.data.mongodb.core.MongoExceptionTranslator;
22+
23+
import com.mongodb.reactivestreams.client.MongoDatabase;
24+
25+
/**
26+
* Interface for factories creating reactive {@link MongoDatabase} instances.
27+
*
28+
* @author Mark Paluch
29+
* @since 2.0
30+
*/
31+
public interface ReactiveMongoDatabaseFactory {
32+
33+
/**
34+
* Creates a default {@link MongoDatabase} instance.
35+
*
36+
* @return
37+
* @throws DataAccessException
38+
*/
39+
MongoDatabase getMongoDatabase() throws DataAccessException;
40+
41+
/**
42+
* Creates a {@link MongoDatabase} instance to access the database with the given name.
43+
*
44+
* @param dbName must not be {@literal null} or empty.
45+
* @return
46+
* @throws DataAccessException
47+
*/
48+
MongoDatabase getMongoDatabase(String dbName) throws DataAccessException;
49+
50+
/**
51+
* Exposes a shared {@link MongoExceptionTranslator}.
52+
*
53+
* @return will never be {@literal null}.
54+
*/
55+
PersistenceExceptionTranslator getExceptionTranslator();
56+
}

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

Lines changed: 4 additions & 159 deletions
Original file line numberDiff line numberDiff line change
@@ -15,36 +15,16 @@
1515
*/
1616
package org.springframework.data.mongodb.config;
1717

18-
import java.util.Collection;
19-
import java.util.Collections;
20-
import java.util.HashSet;
21-
import java.util.Set;
22-
23-
import org.springframework.beans.factory.config.BeanDefinition;
2418
import org.springframework.context.annotation.Bean;
25-
import org.springframework.context.annotation.ClassPathScanningCandidateComponentProvider;
2619
import org.springframework.context.annotation.Configuration;
27-
import org.springframework.core.convert.converter.Converter;
28-
import org.springframework.core.type.filter.AnnotationTypeFilter;
29-
import org.springframework.data.annotation.Persistent;
3020
import org.springframework.data.authentication.UserCredentials;
31-
import org.springframework.data.mapping.context.MappingContextIsNewStrategyFactory;
32-
import org.springframework.data.mapping.model.CamelCaseAbbreviatingFieldNamingStrategy;
33-
import org.springframework.data.mapping.model.FieldNamingStrategy;
34-
import org.springframework.data.mapping.model.PropertyNameFieldNamingStrategy;
3521
import org.springframework.data.mongodb.MongoDbFactory;
3622
import org.springframework.data.mongodb.core.MongoTemplate;
3723
import org.springframework.data.mongodb.core.SimpleMongoDbFactory;
38-
import org.springframework.data.mongodb.core.convert.CustomConversions;
3924
import org.springframework.data.mongodb.core.convert.DbRefResolver;
4025
import org.springframework.data.mongodb.core.convert.DefaultDbRefResolver;
4126
import org.springframework.data.mongodb.core.convert.MappingMongoConverter;
4227
import org.springframework.data.mongodb.core.mapping.Document;
43-
import org.springframework.data.mongodb.core.mapping.MongoMappingContext;
44-
import org.springframework.data.support.CachingIsNewStrategyFactory;
45-
import org.springframework.data.support.IsNewStrategyFactory;
46-
import org.springframework.util.ClassUtils;
47-
import org.springframework.util.StringUtils;
4828

4929
import com.mongodb.Mongo;
5030
import com.mongodb.MongoClient;
@@ -57,16 +37,11 @@
5737
* @author Thomas Darimont
5838
* @author Ryan Tenney
5939
* @author Christoph Strobl
40+
* @author Mark Paluch
41+
* @see MongoConfigurationSupport
6042
*/
6143
@Configuration
62-
public abstract class AbstractMongoConfiguration {
63-
64-
/**
65-
* Return the name of the database to connect to.
66-
*
67-
* @return must not be {@literal null}.
68-
*/
69-
protected abstract String getDatabaseName();
44+
public abstract class AbstractMongoConfiguration extends MongoConfigurationSupport {
7045

7146
/**
7247
* Return the name of the authentication database to use. Defaults to {@literal null} and will turn into the value
@@ -120,7 +95,7 @@ public MongoDbFactory mongoDbFactory() throws Exception {
12095
* class' (the concrete class, not this one here) by default. So if you have a {@code com.acme.AppConfig} extending
12196
* {@link AbstractMongoConfiguration} the base package will be considered {@code com.acme} unless the method is
12297
* overridden to implement alternate behavior.
123-
*
98+
*
12499
* @return the base package to scan for mapped {@link Document} classes or {@literal null} to not enable scanning for
125100
* entities.
126101
* @deprecated use {@link #getMappingBasePackages()} instead.
@@ -132,20 +107,6 @@ protected String getMappingBasePackage() {
132107
return mappingBasePackage == null ? null : mappingBasePackage.getName();
133108
}
134109

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-
149110
/**
150111
* Return {@link UserCredentials} to be used when connecting to the MongoDB instance or {@literal null} if none shall
151112
* be used.
@@ -159,47 +120,6 @@ protected UserCredentials getUserCredentials() {
159120
return null;
160121
}
161122

162-
/**
163-
* Creates a {@link MongoMappingContext} equipped with entity classes scanned from the mapping base package.
164-
*
165-
* @see #getMappingBasePackage()
166-
* @return
167-
* @throws ClassNotFoundException
168-
*/
169-
@Bean
170-
public MongoMappingContext mongoMappingContext() throws ClassNotFoundException {
171-
172-
MongoMappingContext mappingContext = new MongoMappingContext();
173-
mappingContext.setInitialEntitySet(getInitialEntitySet());
174-
mappingContext.setSimpleTypeHolder(customConversions().getSimpleTypeHolder());
175-
mappingContext.setFieldNamingStrategy(fieldNamingStrategy());
176-
177-
return mappingContext;
178-
}
179-
180-
/**
181-
* Returns a {@link MappingContextIsNewStrategyFactory} wrapped into a {@link CachingIsNewStrategyFactory}.
182-
*
183-
* @return
184-
* @throws ClassNotFoundException
185-
*/
186-
@Bean
187-
public IsNewStrategyFactory isNewStrategyFactory() throws ClassNotFoundException {
188-
return new CachingIsNewStrategyFactory(new MappingContextIsNewStrategyFactory(mongoMappingContext()));
189-
}
190-
191-
/**
192-
* Register custom {@link Converter}s in a {@link CustomConversions} object if required. These
193-
* {@link CustomConversions} will be registered with the {@link #mappingMongoConverter()} and
194-
* {@link #mongoMappingContext()}. Returns an empty {@link CustomConversions} instance by default.
195-
*
196-
* @return must not be {@literal null}.
197-
*/
198-
@Bean
199-
public CustomConversions customConversions() {
200-
return new CustomConversions(Collections.emptyList());
201-
}
202-
203123
/**
204124
* Creates a {@link MappingMongoConverter} using the configured {@link #mongoDbFactory()} and
205125
* {@link #mongoMappingContext()}. Will get {@link #customConversions()} applied.
@@ -219,79 +139,4 @@ public MappingMongoConverter mappingMongoConverter() throws Exception {
219139

220140
return converter;
221141
}
222-
223-
/**
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()}.
226-
*
227-
* @see #getMappingBasePackages()
228-
* @return
229-
* @throws ClassNotFoundException
230-
*/
231-
protected Set<Class<?>> getInitialEntitySet() throws ClassNotFoundException {
232-
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-
257-
Set<Class<?>> initialEntitySet = new HashSet<Class<?>>();
258-
259-
if (StringUtils.hasText(basePackage)) {
260-
261-
ClassPathScanningCandidateComponentProvider componentProvider = new ClassPathScanningCandidateComponentProvider(
262-
false);
263-
componentProvider.addIncludeFilter(new AnnotationTypeFilter(Document.class));
264-
componentProvider.addIncludeFilter(new AnnotationTypeFilter(Persistent.class));
265-
266-
for (BeanDefinition candidate : componentProvider.findCandidateComponents(basePackage)) {
267-
268-
initialEntitySet
269-
.add(ClassUtils.forName(candidate.getBeanClassName(), AbstractMongoConfiguration.class.getClassLoader()));
270-
}
271-
}
272-
273-
return initialEntitySet;
274-
}
275-
276-
/**
277-
* Configures whether to abbreviate field names for domain objects by configuring a
278-
* {@link CamelCaseAbbreviatingFieldNamingStrategy} on the {@link MongoMappingContext} instance created. For advanced
279-
* customization needs, consider overriding {@link #mappingMongoConverter()}.
280-
*
281-
* @return
282-
*/
283-
protected boolean abbreviateFieldNames() {
284-
return false;
285-
}
286-
287-
/**
288-
* Configures a {@link FieldNamingStrategy} on the {@link MongoMappingContext} instance created.
289-
*
290-
* @return
291-
* @since 1.5
292-
*/
293-
protected FieldNamingStrategy fieldNamingStrategy() {
294-
return abbreviateFieldNames() ? new CamelCaseAbbreviatingFieldNamingStrategy()
295-
: PropertyNameFieldNamingStrategy.INSTANCE;
296-
}
297142
}

0 commit comments

Comments
 (0)